mirror of
https://github.com/akveo/ngx-admin.git
synced 2025-09-22 05:50:48 +02:00
feat(temperatureDragger): fix some UX issues
This commit is contained in:
parent
03bf3c6590
commit
fe7ef91ada
3 changed files with 36 additions and 25 deletions
|
@ -11,7 +11,7 @@
|
|||
</filter>
|
||||
|
||||
<clipPath id="sliderClip">
|
||||
<path [attr.d]="styles.clipPathStr"></path>
|
||||
<path [attr.d]="styles.clipPathStr" stroke="black"></path>
|
||||
</clipPath>
|
||||
|
||||
</defs>
|
||||
|
@ -24,8 +24,10 @@
|
|||
<path [attr.d]="styles.nonSelectedArc.d" [attr.fill]="styles.nonSelectedArc.color"></path>
|
||||
</g>
|
||||
|
||||
<circle [attr.cx]="styles.knobPosition.x" [attr.cy]="styles.knobPosition.y" [attr.r]="pinRadius"
|
||||
<circle [attr.cx]="styles.thumbPosition.x" [attr.cy]="styles.thumbPosition.y" [attr.r]="pinRadius"
|
||||
[attr.stroke-width]="1 / scaleFactor" fill="#FFFFFF" stroke="#666666"></circle>
|
||||
<circle [attr.cx]="styles.thumbPosition.x" [attr.cy]="styles.thumbPosition.y" [attr.r]="pinDashRadius"
|
||||
[attr.stroke-width]="2 / scaleFactor" fill="none" stroke="#FFFFFF" stroke-linecap="round" stroke-dasharray="1, 6" *ngIf="pinDashRadius"></circle>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
|
|
|
@ -17,7 +17,9 @@ export class TemperatureDraggerComponent implements AfterViewInit, OnChanges {
|
|||
@Input() disableArcColor: string = '#999999';
|
||||
@Input() bottomAngle: number = 90;
|
||||
@Input() arcThickness: number = 20; // CSS pixels
|
||||
@Input() knobRadius: number = 15; // CSS pixels
|
||||
@Input() thumbRadius: number = 15; // CSS pixels
|
||||
@Input() thumbDashRadius: number = null;
|
||||
@Input() maxLeap: number = 0.4;
|
||||
|
||||
value: number = 50;
|
||||
@Output('valueChange') valueChange = new EventEmitter<Number>();
|
||||
|
@ -30,13 +32,13 @@ export class TemperatureDraggerComponent implements AfterViewInit, OnChanges {
|
|||
|
||||
@Output() power = new EventEmitter<boolean>();
|
||||
|
||||
@HostListener('mouseup', ['$event'])
|
||||
@HostListener('window:mouseup', ['$event'])
|
||||
onMouseUp(event) {
|
||||
this.recalculateValue(event);
|
||||
this.isMouseDown = false;
|
||||
}
|
||||
|
||||
@HostListener('mousemove', ['$event'])
|
||||
@HostListener('window:mousemove', ['$event'])
|
||||
onMouseMove(event: MouseEvent) {
|
||||
this.recalculateValue(event);
|
||||
}
|
||||
|
@ -56,6 +58,7 @@ export class TemperatureDraggerComponent implements AfterViewInit, OnChanges {
|
|||
translateYValue = 0;
|
||||
thickness = 6;
|
||||
pinRadius = 10;
|
||||
pinDashRadius = null;
|
||||
colors: any = [];
|
||||
|
||||
styles = {
|
||||
|
@ -64,7 +67,7 @@ export class TemperatureDraggerComponent implements AfterViewInit, OnChanges {
|
|||
clipPathStr: '',
|
||||
gradArcs: [],
|
||||
nonSelectedArc: {},
|
||||
knobPosition: { x: 0, y: 0 },
|
||||
thumbPosition: { x: 0, y: 0 },
|
||||
blurRadius: 15,
|
||||
};
|
||||
|
||||
|
@ -89,7 +92,7 @@ export class TemperatureDraggerComponent implements AfterViewInit, OnChanges {
|
|||
mouseDown(event) {
|
||||
this.isMouseDown = true;
|
||||
if (!this.off) {
|
||||
this.recalculateValue(event);
|
||||
this.recalculateValue(event, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -126,8 +129,9 @@ export class TemperatureDraggerComponent implements AfterViewInit, OnChanges {
|
|||
const svgBoundingRect = this.svgRoot.nativeElement.getBoundingClientRect();
|
||||
const svgAreaFactor = svgBoundingRect.width / svgBoundingRect.height;
|
||||
const svgHeight = VIEW_BOX_SIZE / svgAreaFactor;
|
||||
const knobMargin = this.knobRadius > this.arcThickness
|
||||
? (this.knobRadius - this.arcThickness / 2) / this.scaleFactor
|
||||
const thumbMaxRadius = Math.max(this.thumbRadius, this.thumbDashRadius);
|
||||
const thumbMargin = 2 * thumbMaxRadius > this.arcThickness
|
||||
? (thumbMaxRadius - this.arcThickness / 2) / this.scaleFactor
|
||||
: 0;
|
||||
|
||||
this.scaleFactor = svgBoundingRect.width / VIEW_BOX_SIZE;
|
||||
|
@ -139,13 +143,13 @@ export class TemperatureDraggerComponent implements AfterViewInit, OnChanges {
|
|||
: ( 2 * Math.sin(halfAngle) / (1 + Math.cos(halfAngle)) );
|
||||
if (circleFactor > svgAreaFactor) {
|
||||
if (this.bottomAngleRad > Math.PI) {
|
||||
this.radius = (VIEW_BOX_SIZE - 2 * knobMargin) / (2 * Math.sin(halfAngle));
|
||||
this.radius = (VIEW_BOX_SIZE - 2 * thumbMargin) / (2 * Math.sin(halfAngle));
|
||||
} else {
|
||||
this.radius = VIEW_BOX_SIZE / 2 - knobMargin;
|
||||
this.radius = VIEW_BOX_SIZE / 2 - thumbMargin;
|
||||
}
|
||||
|
||||
} else {
|
||||
this.radius = (svgHeight - 2 * knobMargin) / (1 + Math.cos(halfAngle));
|
||||
this.radius = (svgHeight - 2 * thumbMargin) / (1 + Math.cos(halfAngle));
|
||||
}
|
||||
|
||||
this.translateXValue = VIEW_BOX_SIZE / 2 - this.radius;
|
||||
|
@ -154,10 +158,10 @@ export class TemperatureDraggerComponent implements AfterViewInit, OnChanges {
|
|||
this.styles.arcTranslateStr = `translate(${this.translateXValue}, ${this.translateYValue})`;
|
||||
|
||||
this.thickness = this.arcThickness / this.scaleFactor;
|
||||
this.pinRadius = this.knobRadius / this.scaleFactor;
|
||||
this.pinRadius = this.thumbRadius / this.scaleFactor;
|
||||
this.pinDashRadius = this.thumbDashRadius && this.thumbDashRadius / this.scaleFactor;
|
||||
}
|
||||
|
||||
|
||||
private calculateClipPathSettings() {
|
||||
const halfAngle = this.bottomAngleRad / 2;
|
||||
const innerRadius = this.radius - this.thickness;
|
||||
|
@ -295,14 +299,14 @@ export class TemperatureDraggerComponent implements AfterViewInit, OnChanges {
|
|||
const radiusOffset = this.thickness / 2;
|
||||
const curveRadius = this.radius - radiusOffset;
|
||||
const actualAngle = (2 * Math.PI - this.bottomAngleRad) * this.getValuePercentage() + this.bottomAngleRad / 2;
|
||||
this.styles.knobPosition = {
|
||||
this.styles.thumbPosition = {
|
||||
x: curveRadius * (1 - Math.sin(actualAngle)) + radiusOffset,
|
||||
y: curveRadius * (1 + Math.cos(actualAngle)) + radiusOffset,
|
||||
};
|
||||
this.invalidateNonSelectedArc();
|
||||
}
|
||||
|
||||
private recalculateValue(event) {
|
||||
private recalculateValue(event, allowJumping = false) {
|
||||
if (this.isMouseDown && !this.off) {
|
||||
const rect = this.svgRoot.nativeElement.getBoundingClientRect();
|
||||
const center = {
|
||||
|
@ -314,18 +318,19 @@ export class TemperatureDraggerComponent implements AfterViewInit, OnChanges {
|
|||
actualAngle = actualAngle + 2 * Math.PI;
|
||||
}
|
||||
|
||||
let value = 0;
|
||||
const previousRelativeValue = this.getValuePercentage();
|
||||
let relativeValue = 0;
|
||||
if (actualAngle < this.bottomAngleRad / 2) {
|
||||
value = 0;
|
||||
relativeValue = 0;
|
||||
} else if (actualAngle > 2 * Math.PI - this.bottomAngleRad / 2) {
|
||||
value = 1;
|
||||
relativeValue = 1;
|
||||
} else {
|
||||
value = (actualAngle - this.bottomAngleRad / 2) / (2 * Math.PI - this.bottomAngleRad);
|
||||
relativeValue = (actualAngle - this.bottomAngleRad / 2) / (2 * Math.PI - this.bottomAngleRad);
|
||||
}
|
||||
|
||||
value = value * (this.max - this.min) + this.min;
|
||||
const value = this.toValueNumber(relativeValue);
|
||||
|
||||
if (this.value !== value) {
|
||||
if (this.value !== value && (allowJumping || Math.abs(relativeValue - previousRelativeValue) < this.maxLeap)) {
|
||||
this.value = value;
|
||||
this.valueChange.emit(this.value);
|
||||
this.invalidatePinPosition();
|
||||
|
@ -337,6 +342,10 @@ export class TemperatureDraggerComponent implements AfterViewInit, OnChanges {
|
|||
return (this.value - this.min) / (this.max - this.min);
|
||||
}
|
||||
|
||||
private toValueNumber(factor) {
|
||||
return factor * (this.max - this.min) + this.min;
|
||||
}
|
||||
|
||||
private static toRad(angle) {
|
||||
return Math.PI * angle / 180;
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
<div class="temperature-container">
|
||||
<ngx-temperature-dragger [(value)]="temperature" (power)="temperatureOff = !$event" [min]="12" [max]="30"
|
||||
[arcThickness]="20" [knobRadius]="15" [bottomAngle]="90" [disableArcColor]="themeConfig.layoutBg"
|
||||
[arcThickness]="20" [thumbRadius]="15" [thumbDashRadius]="22" [bottomAngle]="90" [disableArcColor]="themeConfig.layoutBg"
|
||||
[fillColors]="[themeConfig.colorInfo, themeConfig.colorSuccess, themeConfig.colorWarning]">
|
||||
|
||||
<div class="temperature" [ngClass]="{ 'off': temperatureOff }">
|
||||
|
@ -41,7 +41,7 @@
|
|||
<span>Humidity placeholder</span>
|
||||
|
||||
<!--<ngx-temperature-dragger [(value)]="humidity" (power)="humidityOff = !$event" [min]="0" [max]="100"-->
|
||||
<!--[arcThickness]="20" [knobRadius]="15" [bottomAngle]="90" [disableArcColor]="themeConfig.layoutBg"-->
|
||||
<!--[arcThickness]="20" [thumbRadius]="15" [bottomAngle]="90" [disableArcColor]="themeConfig.layoutBg"-->
|
||||
<!--[fillColors]="[themeConfig.colorInfo, themeConfig.colorSuccess, themeConfig.colorWarning]">-->
|
||||
|
||||
<!--<div class="temperature" [ngClass]="{ 'off': humidityOff }">-->
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue