fix event listener registration & unregistration
This commit is contained in:
parent
b07ae0406f
commit
f52f7b406b
|
@ -261,57 +261,105 @@ export class PanZoom extends EventEmitter<PanZoomEvents> {
|
||||||
}
|
}
|
||||||
|
|
||||||
registerTouchEvents() {
|
registerTouchEvents() {
|
||||||
|
console.debug("[PanZoom] Registering touch events to $wrapper");
|
||||||
|
|
||||||
this.$wrapper.addEventListener(
|
this.$wrapper.addEventListener(
|
||||||
"touchstart",
|
"touchstart",
|
||||||
(event) => {
|
this._touch_touchstart.bind(this),
|
||||||
const isDoubleTap =
|
{
|
||||||
this.touch.lastTouch && +new Date() - this.touch.lastTouch < 200;
|
passive: false,
|
||||||
|
}
|
||||||
if (isDoubleTap && event.touches.length === 1) {
|
|
||||||
this.emit("doubleTap", event);
|
|
||||||
} else {
|
|
||||||
this.touch.lastTouch = +new Date();
|
|
||||||
|
|
||||||
const { touches } = event;
|
|
||||||
|
|
||||||
const isPanningAction = touches.length === 1;
|
|
||||||
const isPinchAction = touches.length === 2;
|
|
||||||
|
|
||||||
if (isPanningAction) {
|
|
||||||
this.panning.start(touches[0].clientX, touches[0].clientY);
|
|
||||||
}
|
|
||||||
if (isPinchAction) {
|
|
||||||
this.onPinchStart(event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{ passive: false }
|
|
||||||
);
|
);
|
||||||
|
|
||||||
this.$wrapper.addEventListener("touchmove", (event) => {
|
this.$wrapper.addEventListener(
|
||||||
if (this.panning.enabled && event.touches.length === 1) {
|
"touchmove",
|
||||||
event.preventDefault();
|
this._touch_touchmove.bind(this)
|
||||||
event.stopPropagation();
|
);
|
||||||
|
|
||||||
const touch = event.touches[0];
|
this.$wrapper.addEventListener("touchend", this._touch_touchend.bind(this));
|
||||||
|
|
||||||
this.panning.move(touch.clientX, touch.clientY);
|
|
||||||
} else if (event.touches.length > 1) {
|
|
||||||
this.onPinch(event);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
this.$wrapper.addEventListener("touchend", (event) => {
|
|
||||||
if (this.panning.enabled) {
|
|
||||||
this.panning.enabled = false;
|
|
||||||
|
|
||||||
const touch = event.changedTouches[0];
|
|
||||||
|
|
||||||
this.panning.end(touch.clientX, touch.clientY);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unregisterTouchEvents() {
|
||||||
|
console.debug("[PanZoom] Unregistering touch events to $wrapper");
|
||||||
|
|
||||||
|
this.$wrapper.removeEventListener(
|
||||||
|
"touchstart",
|
||||||
|
this._touch_touchstart.bind(this)
|
||||||
|
);
|
||||||
|
this.$wrapper.removeEventListener(
|
||||||
|
"touchmove",
|
||||||
|
this._touch_touchmove.bind(this)
|
||||||
|
);
|
||||||
|
this.$wrapper.removeEventListener(
|
||||||
|
"touchend",
|
||||||
|
this._touch_touchend.bind(this)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle touchstart event from touch registrations
|
||||||
|
* This needs to be a variable to correctly pass this context
|
||||||
|
*
|
||||||
|
* @param e
|
||||||
|
*/
|
||||||
|
private _touch_touchstart = (event: TouchEvent) => {
|
||||||
|
const isDoubleTap =
|
||||||
|
this.touch.lastTouch && +new Date() - this.touch.lastTouch < 200;
|
||||||
|
|
||||||
|
if (isDoubleTap && event.touches.length === 1) {
|
||||||
|
this.emit("doubleTap", event);
|
||||||
|
} else {
|
||||||
|
this.touch.lastTouch = +new Date();
|
||||||
|
|
||||||
|
const { touches } = event;
|
||||||
|
|
||||||
|
const isPanningAction = touches.length === 1;
|
||||||
|
const isPinchAction = touches.length === 2;
|
||||||
|
|
||||||
|
if (isPanningAction) {
|
||||||
|
this.panning.start(touches[0].clientX, touches[0].clientY);
|
||||||
|
}
|
||||||
|
if (isPinchAction) {
|
||||||
|
this.onPinchStart(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle touchmove event from touch registrations
|
||||||
|
* This needs to be a variable to correctly pass this context
|
||||||
|
*
|
||||||
|
* @param e
|
||||||
|
*/
|
||||||
|
private _touch_touchmove = (event: TouchEvent) => {
|
||||||
|
if (this.panning.enabled && event.touches.length === 1) {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
|
||||||
|
const touch = event.touches[0];
|
||||||
|
|
||||||
|
this.panning.move(touch.clientX, touch.clientY);
|
||||||
|
} else if (event.touches.length > 1) {
|
||||||
|
this.onPinch(event);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle touchend event from touch registrations
|
||||||
|
* This needs to be a variable to correctly pass this context
|
||||||
|
*
|
||||||
|
* @param e
|
||||||
|
*/
|
||||||
|
private _touch_touchend = (event: TouchEvent) => {
|
||||||
|
if (this.panning.enabled) {
|
||||||
|
this.panning.enabled = false;
|
||||||
|
|
||||||
|
const touch = event.changedTouches[0];
|
||||||
|
|
||||||
|
this.panning.end(touch.clientX, touch.clientY);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/// /////
|
/// /////
|
||||||
// pinch
|
// pinch
|
||||||
/// /////
|
/// /////
|
||||||
|
@ -396,115 +444,167 @@ export class PanZoom extends EventEmitter<PanZoomEvents> {
|
||||||
}
|
}
|
||||||
|
|
||||||
registerMouseEvents() {
|
registerMouseEvents() {
|
||||||
|
console.debug("[PanZoom] Registering mouse events to $wrapper & document");
|
||||||
|
|
||||||
// zoom
|
// zoom
|
||||||
this.$wrapper.addEventListener(
|
this.$wrapper.addEventListener("wheel", this._mouse_wheel, {
|
||||||
"wheel",
|
passive: true,
|
||||||
(e) => {
|
});
|
||||||
// if (!self.allowDrag) return;
|
|
||||||
const oldScale = this.transform.scale;
|
|
||||||
|
|
||||||
let delta = -e.deltaY;
|
this.$wrapper.addEventListener("mousedown", this._mouse_mousedown, {
|
||||||
|
passive: false,
|
||||||
switch (e.deltaMode) {
|
});
|
||||||
case WheelEvent.DOM_DELTA_PIXEL:
|
|
||||||
// 53 pixels is the default chrome gives for a wheel scroll.
|
|
||||||
delta /= 53;
|
|
||||||
break;
|
|
||||||
case WheelEvent.DOM_DELTA_LINE:
|
|
||||||
// default case on Firefox, three lines is default number.
|
|
||||||
delta /= 3;
|
|
||||||
break;
|
|
||||||
case WheelEvent.DOM_DELTA_PAGE:
|
|
||||||
delta = Math.sign(delta);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: move this to settings
|
|
||||||
this.nudgeScale(delta / 2);
|
|
||||||
|
|
||||||
const scale = this.transform.scale;
|
|
||||||
if (oldScale !== scale) {
|
|
||||||
const dx = e.clientX - this.$wrapper.clientWidth / 2;
|
|
||||||
const dy = e.clientY - this.$wrapper.clientHeight / 2;
|
|
||||||
this.transform.x -= dx / oldScale;
|
|
||||||
this.transform.x += dx / scale;
|
|
||||||
this.transform.y -= dy / oldScale;
|
|
||||||
this.transform.y += dy / scale;
|
|
||||||
this.update();
|
|
||||||
// place.update();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{ passive: true }
|
|
||||||
);
|
|
||||||
|
|
||||||
this.$wrapper.addEventListener(
|
|
||||||
"mousedown",
|
|
||||||
(e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
|
||||||
|
|
||||||
this.mouse.mouseDown = Date.now();
|
|
||||||
|
|
||||||
this.panning.start(e.clientX, e.clientY);
|
|
||||||
},
|
|
||||||
{ passive: false }
|
|
||||||
);
|
|
||||||
|
|
||||||
// mouse move should not be tied to the element, in case the mouse exits the window
|
// mouse move should not be tied to the element, in case the mouse exits the window
|
||||||
document.addEventListener(
|
document.addEventListener("mousemove", this._mouse_mousemove, {
|
||||||
"mousemove",
|
passive: false,
|
||||||
(e) => {
|
});
|
||||||
if (this.panning.enabled) {
|
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
|
||||||
|
|
||||||
this.panning.move(e.clientX, e.clientY);
|
|
||||||
} else {
|
|
||||||
// not panning
|
|
||||||
this.emit("hover", {
|
|
||||||
clientX: e.clientX,
|
|
||||||
clientY: e.clientY,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{ passive: false }
|
|
||||||
);
|
|
||||||
|
|
||||||
// mouse up should not be tied to the element, in case the mouse releases outside of the window
|
// mouse up should not be tied to the element, in case the mouse releases outside of the window
|
||||||
document.addEventListener(
|
document.addEventListener("mouseup", this._mouse_mouseup, {
|
||||||
"mouseup",
|
passive: false,
|
||||||
(e) => {
|
});
|
||||||
if (this.mouse.mouseDown && Date.now() - this.mouse.mouseDown <= 500) {
|
|
||||||
// if the mouse was down for less than a half a second, it's a click
|
|
||||||
// this can't depend on this.panning.enabled because that'll always be true when mouse is down
|
|
||||||
|
|
||||||
const delta = [
|
|
||||||
Math.abs(this.panning.x - e.clientX),
|
|
||||||
Math.abs(this.panning.y - e.clientY),
|
|
||||||
];
|
|
||||||
|
|
||||||
if (delta[0] < 5 && delta[1] < 5) {
|
|
||||||
// difference from the start position to the up position is very very slow,
|
|
||||||
// so it's most likely intended to be a click
|
|
||||||
this.emit("click", {
|
|
||||||
clientX: e.clientX,
|
|
||||||
clientY: e.clientY,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.panning.enabled) {
|
|
||||||
// currently panning
|
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
|
||||||
|
|
||||||
this.panning.end(e.clientX, e.clientY);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{ passive: false }
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unregisterMouseEvents() {
|
||||||
|
console.debug(
|
||||||
|
"[PanZoom] Unregistering mouse events to $wrapper & document"
|
||||||
|
);
|
||||||
|
|
||||||
|
this.$wrapper.removeEventListener("wheel", this._mouse_wheel);
|
||||||
|
|
||||||
|
this.$wrapper.removeEventListener("mousedown", this._mouse_mousedown);
|
||||||
|
|
||||||
|
document.removeEventListener("mousemove", this._mouse_mousemove);
|
||||||
|
|
||||||
|
document.removeEventListener("mouseup", this._mouse_mouseup);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the wheel event from the mouse event registration
|
||||||
|
* This needs to be a variable to correctly pass this context
|
||||||
|
*
|
||||||
|
* @param e
|
||||||
|
*/
|
||||||
|
private _mouse_wheel = (e: WheelEvent) => {
|
||||||
|
// if (!self.allowDrag) return;
|
||||||
|
const oldScale = this.transform.scale;
|
||||||
|
|
||||||
|
let delta = -e.deltaY;
|
||||||
|
|
||||||
|
switch (e.deltaMode) {
|
||||||
|
case WheelEvent.DOM_DELTA_PIXEL:
|
||||||
|
// 53 pixels is the default chrome gives for a wheel scroll.
|
||||||
|
delta /= 53;
|
||||||
|
break;
|
||||||
|
case WheelEvent.DOM_DELTA_LINE:
|
||||||
|
// default case on Firefox, three lines is default number.
|
||||||
|
delta /= 3;
|
||||||
|
break;
|
||||||
|
case WheelEvent.DOM_DELTA_PAGE:
|
||||||
|
delta = Math.sign(delta);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: move this to settings
|
||||||
|
this.nudgeScale(delta / 2);
|
||||||
|
|
||||||
|
const scale = this.transform.scale;
|
||||||
|
if (oldScale !== scale) {
|
||||||
|
const dx = e.clientX - this.$wrapper.clientWidth / 2;
|
||||||
|
const dy = e.clientY - this.$wrapper.clientHeight / 2;
|
||||||
|
this.transform.x -= dx / oldScale;
|
||||||
|
this.transform.x += dx / scale;
|
||||||
|
this.transform.y -= dy / oldScale;
|
||||||
|
this.transform.y += dy / scale;
|
||||||
|
this.update();
|
||||||
|
// place.update();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle mousedown event from mouse registrations
|
||||||
|
* This needs to be a variable to correctly pass this context
|
||||||
|
*
|
||||||
|
* @param e
|
||||||
|
*/
|
||||||
|
private _mouse_mousedown = (e: MouseEvent) => {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
|
||||||
|
this.mouse.mouseDown = Date.now();
|
||||||
|
|
||||||
|
this.panning.start(e.clientX, e.clientY);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle mousemove event from mouse registrations
|
||||||
|
* This needs to be a variable to correctly pass this context
|
||||||
|
*
|
||||||
|
* @param e
|
||||||
|
*/
|
||||||
|
private _mouse_mousemove = (e: MouseEvent) => {
|
||||||
|
if (this.panning.enabled) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
|
||||||
|
this.panning.move(e.clientX, e.clientY);
|
||||||
|
} else {
|
||||||
|
// not panning
|
||||||
|
this.emit("hover", {
|
||||||
|
clientX: e.clientX,
|
||||||
|
clientY: e.clientY,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (this.panning.enabled) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
|
||||||
|
this.panning.move(e.clientX, e.clientY);
|
||||||
|
} else {
|
||||||
|
// not panning
|
||||||
|
this.emit("hover", {
|
||||||
|
clientX: e.clientX,
|
||||||
|
clientY: e.clientY,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle mouseup event from mouse registrations
|
||||||
|
* This needs to be a variable to correctly pass this context
|
||||||
|
*
|
||||||
|
* @param e
|
||||||
|
*/
|
||||||
|
private _mouse_mouseup = (e: MouseEvent) => {
|
||||||
|
if (this.mouse.mouseDown && Date.now() - this.mouse.mouseDown <= 500) {
|
||||||
|
// if the mouse was down for less than a half a second, it's a click
|
||||||
|
// this can't depend on this.panning.enabled because that'll always be true when mouse is down
|
||||||
|
|
||||||
|
const delta = [
|
||||||
|
Math.abs(this.panning.x - e.clientX),
|
||||||
|
Math.abs(this.panning.y - e.clientY),
|
||||||
|
];
|
||||||
|
|
||||||
|
if (delta[0] < 5 && delta[1] < 5) {
|
||||||
|
// difference from the start position to the up position is very very slow,
|
||||||
|
// so it's most likely intended to be a click
|
||||||
|
this.emit("click", {
|
||||||
|
clientX: e.clientX,
|
||||||
|
clientY: e.clientY,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.panning.enabled) {
|
||||||
|
// currently panning
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
|
||||||
|
this.panning.end(e.clientX, e.clientY);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update viewport scale and position
|
* Update viewport scale and position
|
||||||
*
|
*
|
||||||
|
@ -545,6 +645,9 @@ export class PanZoom extends EventEmitter<PanZoomEvents> {
|
||||||
|
|
||||||
cleanup() {
|
cleanup() {
|
||||||
// remove event handlers
|
// remove event handlers
|
||||||
|
|
||||||
|
this.unregisterTouchEvents();
|
||||||
|
this.unregisterMouseEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
// utilities
|
// utilities
|
||||||
|
|
Loading…
Reference in New Issue