|
|
@@ -1,38 +1,35 @@
|
|
|
-
|
|
|
-type DragCallback = (dx: number, dy: number) => void
|
|
|
-type ZoomCallback = (scale: number, focusX: number, focusY: number) => void
|
|
|
-type TapCallback = (dx: number, dy: number) => void
|
|
|
+type DragCallback = (dx: number, dy: number) => void;
|
|
|
+type ZoomCallback = (scale: number, focusX: number, focusY: number) => void;
|
|
|
+type TapCallback = (dx: number, dy: number) => void;
|
|
|
|
|
|
export interface Callbacks {
|
|
|
- drag?: DragCallback,
|
|
|
- zoom?: ZoomCallback,
|
|
|
- tap?: TapCallback,
|
|
|
+ drag?: DragCallback;
|
|
|
+ zoom?: ZoomCallback;
|
|
|
+ tap?: TapCallback;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-
|
|
|
interface MyTouch {
|
|
|
- identifier: number,
|
|
|
- lastX: number,
|
|
|
- lastY: number,
|
|
|
- dx: number,
|
|
|
- dy: number,
|
|
|
+ identifier: number;
|
|
|
+ lastX: number;
|
|
|
+ lastY: number;
|
|
|
+ dx: number;
|
|
|
+ dy: number;
|
|
|
}
|
|
|
|
|
|
interface ScaleTracker {
|
|
|
- focusX: number,
|
|
|
- focusY: number,
|
|
|
- distance: number,
|
|
|
+ focusX: number;
|
|
|
+ focusY: number;
|
|
|
+ distance: number;
|
|
|
}
|
|
|
|
|
|
export class TouchTracker {
|
|
|
- touches: Array<MyTouch> = []
|
|
|
+ touches: Array<MyTouch> = [];
|
|
|
callbacks: Callbacks;
|
|
|
el: HTMLElement;
|
|
|
|
|
|
- scaleTracker?: ScaleTracker
|
|
|
+ scaleTracker?: ScaleTracker;
|
|
|
|
|
|
- distance = 0
|
|
|
+ distance = 0;
|
|
|
|
|
|
constructor(el: HTMLElement, callbacks: Callbacks) {
|
|
|
this.callbacks = callbacks;
|
|
|
@@ -40,28 +37,27 @@ export class TouchTracker {
|
|
|
}
|
|
|
|
|
|
private removeTouch(identifier: number) {
|
|
|
- let index = this.touches.findIndex(t => t.identifier == identifier)
|
|
|
+ let index = this.touches.findIndex((t) => t.identifier == identifier);
|
|
|
if (index >= 0) {
|
|
|
- this.touches.splice(index, 1)
|
|
|
+ this.touches.splice(index, 1);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
private getTouch(identifier: number): MyTouch | null {
|
|
|
- let index = this.touches.findIndex(t => t.identifier == identifier)
|
|
|
- if (index >= 0) return this.touches[index]
|
|
|
- else return null
|
|
|
+ let index = this.touches.findIndex((t) => t.identifier == identifier);
|
|
|
+ if (index >= 0) return this.touches[index];
|
|
|
+ else return null;
|
|
|
}
|
|
|
|
|
|
private getX(touch: Touch) {
|
|
|
- //return touch.pageX - this.el.offsetLeft
|
|
|
- return touch.pageX
|
|
|
+ const rect = this.el.getBoundingClientRect();
|
|
|
+ return touch.clientX - rect.left;
|
|
|
}
|
|
|
private getY(touch: Touch) {
|
|
|
- //return touch.pageY - this.el.offsetTop
|
|
|
- return touch.pageY
|
|
|
+ const rect = this.el.getBoundingClientRect();
|
|
|
+ return touch.clientY - rect.top;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
start(list: TouchList) {
|
|
|
for (var i = 0; i < list.length; i++) {
|
|
|
let touch = list[i];
|
|
|
@@ -71,8 +67,8 @@ export class TouchTracker {
|
|
|
lastY: this.getY(touch),
|
|
|
dx: 0,
|
|
|
dy: 0,
|
|
|
- identifier: touch.identifier
|
|
|
- })
|
|
|
+ identifier: touch.identifier,
|
|
|
+ });
|
|
|
}
|
|
|
|
|
|
if (this.touches.length == 1) {
|
|
|
@@ -80,13 +76,12 @@ export class TouchTracker {
|
|
|
}
|
|
|
|
|
|
this.updateFocus();
|
|
|
-
|
|
|
}
|
|
|
|
|
|
updateFocus() {
|
|
|
if (this.touches.length < 2) {
|
|
|
this.scaleTracker = undefined;
|
|
|
- return
|
|
|
+ return;
|
|
|
}
|
|
|
|
|
|
let t1 = this.touches[0];
|
|
|
@@ -94,13 +89,14 @@ export class TouchTracker {
|
|
|
|
|
|
let focusX = (t1.lastX + t2.lastX) / 2;
|
|
|
let focusY = (t1.lastY + t2.lastY) / 2;
|
|
|
- let distance = Math.sqrt(Math.pow(t2.lastX - t1.lastX, 2) + Math.pow(t2.lastY - t1.lastY, 2));
|
|
|
- this.scaleTracker = { focusX, focusY, distance }
|
|
|
+ let distance = Math.sqrt(
|
|
|
+ Math.pow(t2.lastX - t1.lastX, 2) + Math.pow(t2.lastY - t1.lastY, 2),
|
|
|
+ );
|
|
|
+ this.scaleTracker = { focusX, focusY, distance };
|
|
|
}
|
|
|
|
|
|
-
|
|
|
end(list: TouchList) {
|
|
|
- console.log('end')
|
|
|
+ console.log("end");
|
|
|
for (var i = 0; i < list.length; i++) {
|
|
|
this.removeTouch(list[i].identifier);
|
|
|
}
|
|
|
@@ -108,32 +104,34 @@ export class TouchTracker {
|
|
|
|
|
|
if (this.touches.length <= 0 && this.distance == 0) {
|
|
|
let touch = list[0];
|
|
|
- let el = touch.target as HTMLElement
|
|
|
+ const rect = this.el.getBoundingClientRect();
|
|
|
//console.log('kkkkkk', el.offsetLeft, el.offsetTop)
|
|
|
- //this.callbacks?.tap?.(touch.clientX - el.offsetLeft, touch.clientY - el.offsetTop)
|
|
|
- this.callbacks?.tap?.(touch.clientX , touch.clientY)
|
|
|
+ this.callbacks?.tap?.(
|
|
|
+ touch.clientX - rect.left,
|
|
|
+ touch.clientY - rect.top,
|
|
|
+ );
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-
|
|
|
move(list: TouchList) {
|
|
|
for (var i = 0; i < list.length; i++) {
|
|
|
let touch = list[i];
|
|
|
let mytouch = this.getTouch(touch.identifier);
|
|
|
if (mytouch == null) continue;
|
|
|
- mytouch.dx = this.getX(touch) - mytouch.lastX
|
|
|
- mytouch.dy = this.getY(touch) - mytouch.lastY
|
|
|
- mytouch.lastX = this.getX(touch)
|
|
|
- mytouch.lastY = this.getY(touch)
|
|
|
+ mytouch.dx = this.getX(touch) - mytouch.lastX;
|
|
|
+ mytouch.dy = this.getY(touch) - mytouch.lastY;
|
|
|
+ mytouch.lastX = this.getX(touch);
|
|
|
+ mytouch.lastY = this.getY(touch);
|
|
|
|
|
|
if (this.scaleTracker) {
|
|
|
-
|
|
|
let t1 = this.touches[0];
|
|
|
let t2 = this.touches[1];
|
|
|
|
|
|
let focusX = (t1.lastX + t2.lastX) / 2;
|
|
|
let focusY = (t1.lastY + t2.lastY) / 2;
|
|
|
- let distance = Math.sqrt(Math.pow(t2.lastX - t1.lastX, 2) + Math.pow(t2.lastY - t1.lastY, 2));
|
|
|
+ let distance = Math.sqrt(
|
|
|
+ Math.pow(t2.lastX - t1.lastX, 2) + Math.pow(t2.lastY - t1.lastY, 2),
|
|
|
+ );
|
|
|
let dx = focusX - this.scaleTracker.focusX;
|
|
|
let dy = focusY - this.scaleTracker.focusY;
|
|
|
|
|
|
@@ -148,100 +146,78 @@ export class TouchTracker {
|
|
|
this.scaleTracker.focusY = focusY;
|
|
|
this.scaleTracker.distance = distance;
|
|
|
|
|
|
- this.distance += Math.abs(dx) + Math.abs(dy)
|
|
|
-
|
|
|
-
|
|
|
+ this.distance += Math.abs(dx) + Math.abs(dy);
|
|
|
} else {
|
|
|
//if(mytouch.dx > 0 || mytouch.dy >0) {
|
|
|
- this.callbacks.drag?.(mytouch.dx, mytouch.dy)
|
|
|
+ this.callbacks.drag?.(mytouch.dx, mytouch.dy);
|
|
|
// }
|
|
|
- this.distance += Math.abs(mytouch.dx) + Math.abs(mytouch.dy)
|
|
|
+ this.distance += Math.abs(mytouch.dx) + Math.abs(mytouch.dy);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
}
|
|
|
|
|
|
-
|
|
|
export class Gesture {
|
|
|
-
|
|
|
-
|
|
|
constructor(el: HTMLElement, callbacks: Callbacks) {
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
var dx, dy;
|
|
|
var isDown = false;
|
|
|
var lastX: number = 0;
|
|
|
var lastY: number = 0;
|
|
|
var distance = 0;
|
|
|
|
|
|
- el.addEventListener('mousedown', e => {
|
|
|
+ el.addEventListener("mousedown", (e) => {
|
|
|
isDown = true;
|
|
|
lastX = e.clientX;
|
|
|
lastY = e.clientY;
|
|
|
distance = 0;
|
|
|
- })
|
|
|
+ });
|
|
|
|
|
|
- document.addEventListener('mouseup', e => {
|
|
|
+ document.addEventListener("mouseup", (e) => {
|
|
|
isDown = false;
|
|
|
if (distance == 0 && e.target == el) {
|
|
|
- callbacks.tap?.(e.offsetX, e.offsetY)
|
|
|
+ callbacks.tap?.(e.offsetX, e.offsetY);
|
|
|
}
|
|
|
- })
|
|
|
-
|
|
|
+ });
|
|
|
|
|
|
- document.addEventListener('mousemove', e => {
|
|
|
+ document.addEventListener("mousemove", (e) => {
|
|
|
if (isDown) {
|
|
|
- e.preventDefault()
|
|
|
+ e.preventDefault();
|
|
|
dx = e.clientX - lastX;
|
|
|
dy = e.clientY - lastY;
|
|
|
lastX = e.clientX;
|
|
|
lastY = e.clientY;
|
|
|
- distance += Math.abs(dx) + Math.abs(dy)
|
|
|
+ distance += Math.abs(dx) + Math.abs(dy);
|
|
|
callbacks?.drag?.(dx, dy);
|
|
|
}
|
|
|
- })
|
|
|
+ });
|
|
|
|
|
|
- el.addEventListener('wheel', e => {
|
|
|
- e.preventDefault()
|
|
|
+ el.addEventListener("wheel", (e) => {
|
|
|
+ e.preventDefault();
|
|
|
let scale = e.deltaY * -0.01 + 1;
|
|
|
- callbacks.zoom?.(scale, e.offsetX, e.offsetY)
|
|
|
- })
|
|
|
+ callbacks.zoom?.(scale, e.offsetX, e.offsetY);
|
|
|
+ });
|
|
|
|
|
|
- el.addEventListener('click', e => {
|
|
|
- e.preventDefault()
|
|
|
+ el.addEventListener("click", (e) => {
|
|
|
+ e.preventDefault();
|
|
|
//callbacks.tap?.(e.offsetX, e.offsetY)
|
|
|
- })
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
+ });
|
|
|
|
|
|
const tracker = new TouchTracker(el, callbacks);
|
|
|
|
|
|
-
|
|
|
-
|
|
|
- el.addEventListener('touchstart', e => {
|
|
|
+ el.addEventListener("touchstart", (e) => {
|
|
|
e.preventDefault();
|
|
|
tracker.start(e.changedTouches);
|
|
|
- })
|
|
|
-
|
|
|
- el.addEventListener('touchmove', e => {
|
|
|
- tracker.move(e.changedTouches)
|
|
|
- })
|
|
|
-
|
|
|
- el.addEventListener('touchend', e => {
|
|
|
- tracker.end(e.changedTouches)
|
|
|
- })
|
|
|
- el.addEventListener('touchcancel', e => {
|
|
|
- tracker.end(e.changedTouches)
|
|
|
- })
|
|
|
-
|
|
|
-
|
|
|
+ });
|
|
|
+
|
|
|
+ el.addEventListener("touchmove", (e) => {
|
|
|
+ tracker.move(e.changedTouches);
|
|
|
+ });
|
|
|
+
|
|
|
+ el.addEventListener("touchend", (e) => {
|
|
|
+ tracker.end(e.changedTouches);
|
|
|
+ });
|
|
|
+ el.addEventListener("touchcancel", (e) => {
|
|
|
+ tracker.end(e.changedTouches);
|
|
|
+ });
|
|
|
}
|
|
|
}
|
|
|
-
|