mirror of
https://github.com/BookStackApp/BookStack.git
synced 2024-12-12 13:33:46 +08:00
76 lines
2.5 KiB
TypeScript
76 lines
2.5 KiB
TypeScript
|
|
||
|
export type MouseDragTrackerDistance = {
|
||
|
x: number;
|
||
|
y: number;
|
||
|
}
|
||
|
|
||
|
export type MouseDragTrackerOptions = {
|
||
|
down?: (event: MouseEvent, element: HTMLElement) => any;
|
||
|
move?: (event: MouseEvent, element: HTMLElement, distance: MouseDragTrackerDistance) => any;
|
||
|
up?: (event: MouseEvent, element: HTMLElement, distance: MouseDragTrackerDistance) => any;
|
||
|
}
|
||
|
|
||
|
export class MouseDragTracker {
|
||
|
protected container: HTMLElement;
|
||
|
protected dragTargetSelector: string;
|
||
|
protected options: MouseDragTrackerOptions;
|
||
|
|
||
|
protected startX: number = 0;
|
||
|
protected startY: number = 0;
|
||
|
protected target: HTMLElement|null = null;
|
||
|
|
||
|
constructor(container: HTMLElement, dragTargetSelector: string, options: MouseDragTrackerOptions) {
|
||
|
this.container = container;
|
||
|
this.dragTargetSelector = dragTargetSelector;
|
||
|
this.options = options;
|
||
|
|
||
|
this.onMouseDown = this.onMouseDown.bind(this);
|
||
|
this.onMouseMove = this.onMouseMove.bind(this);
|
||
|
this.onMouseUp = this.onMouseUp.bind(this);
|
||
|
this.container.addEventListener('mousedown', this.onMouseDown);
|
||
|
}
|
||
|
|
||
|
teardown() {
|
||
|
this.container.removeEventListener('mousedown', this.onMouseDown);
|
||
|
this.container.removeEventListener('mouseup', this.onMouseUp);
|
||
|
this.container.removeEventListener('mousemove', this.onMouseMove);
|
||
|
}
|
||
|
|
||
|
protected onMouseDown(event: MouseEvent) {
|
||
|
this.target = (event.target as HTMLElement).closest(this.dragTargetSelector);
|
||
|
if (!this.target) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
this.startX = event.screenX;
|
||
|
this.startY = event.screenY;
|
||
|
|
||
|
window.addEventListener('mousemove', this.onMouseMove);
|
||
|
window.addEventListener('mouseup', this.onMouseUp);
|
||
|
if (this.options.down) {
|
||
|
this.options.down(event, this.target);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
protected onMouseMove(event: MouseEvent) {
|
||
|
if (this.options.move && this.target) {
|
||
|
this.options.move(event, this.target, {
|
||
|
x: event.screenX - this.startX,
|
||
|
y: event.screenY - this.startY,
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
|
||
|
protected onMouseUp(event: MouseEvent) {
|
||
|
window.removeEventListener('mousemove', this.onMouseMove);
|
||
|
window.removeEventListener('mouseup', this.onMouseUp);
|
||
|
|
||
|
if (this.options.up && this.target) {
|
||
|
this.options.up(event, this.target, {
|
||
|
x: event.screenX - this.startX,
|
||
|
y: event.screenY - this.startY,
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|