@marcj/angular-desktop-ui
Version:
library offering you desktop UI widgets in Angular 7+
103 lines (87 loc) • 3.33 kB
text/typescript
import {
AfterViewInit,
ChangeDetectorRef,
Component,
ElementRef,
Injector,
Input,
SkipSelf,
ViewChild
} from "@angular/core";
import {ngValueAccessor, ValueAccessorBase} from "../../core/form";
import Hammer from "hammerjs";
export class SliderComponent extends ValueAccessorBase<number> implements AfterViewInit {
knob?: ElementRef;
min = 0;
steps = 0.01;
max = 1;
mini: boolean | '' = false;
constructor(
protected injector: Injector,
public readonly cd: ChangeDetectorRef,
public readonly cdParent: ChangeDetectorRef,
protected element: ElementRef,
) {
super(injector, cd, cdParent);
}
getWidth(): number {
return Math.max(0, Math.min(1, ((this.innerValue || this.min) - this.min) / (this.max - this.min)));
}
ngAfterViewInit() {
const mc = new Hammer(this.knob!.nativeElement);
mc.add(new Hammer.Pan({direction: Hammer.DIRECTION_HORIZONTAL, threshold: 1}));
const mcTab = new Hammer(this.element.nativeElement);
mcTab.add(new Hammer.Tap({}));
let startXInPixels = 0;
let knobSize = this.knob!.nativeElement.offsetWidth;
let width = (this.element!.nativeElement.offsetWidth - knobSize);
let lastRequest: any;
mc.on('panstart', (event: HammerInput) => {
startXInPixels = this.getWidth() * width;
knobSize = this.knob!.nativeElement.offsetWidth;
width = (this.element!.nativeElement.offsetWidth - knobSize)
});
mcTab.on('tapstart', (event: HammerInput) => {
console.log('tabstart', event);
});
const handleNewLeft = (newLeft: number) => {
if (newLeft === 1.0) {
this.innerValue = this.max;
return;
}
let newPotentialValue = this.min + (newLeft * ((this.max - this.min)));
const shift = (newPotentialValue % this.steps);
this.innerValue = Math.max(this.min, newPotentialValue - shift);
};
mcTab.on('tap', (event: HammerInput) => {
const rect = (this.element!.nativeElement as HTMLElement).getBoundingClientRect();
const x = event.center.x - (knobSize / 2) - rect.x;
const newLeft = Math.min(width, Math.max(0, x)) / width;
handleNewLeft(newLeft);
});
mc.on('pan', (event: HammerInput) => {
if (lastRequest) {
cancelAnimationFrame(lastRequest);
}
lastRequest = requestAnimationFrame(() => {
const newLeft = Math.min(width, Math.max(0, (startXInPixels + event.deltaX))) / width;
handleNewLeft(newLeft);
});
});
}
}