Skip to content

Instantly share code, notes, and snippets.

@yuqianma
Last active June 21, 2022 03:15
Show Gist options
  • Save yuqianma/f4db109962dde8020084c46c6f89d5a5 to your computer and use it in GitHub Desktop.
Save yuqianma/f4db109962dde8020084c46c6f89d5a5 to your computer and use it in GitHub Desktop.
zrender custom gesture pan. The element can be panned outside the canvas.
import HandlerProxy from 'zrender/src/dom/HandlerProxy';
// You can also use the `addEventListener` to implement the `docHandlerProxy.on` below
// There's no much difference.
const param = target => ({target});
export default function GestureMouse (handler) {
let checkingTarget = null,
panningTarget = null;
const docHandlerProxy = new HandlerProxy(document);
docHandlerProxy.handler = handler; // prevent error if touch event fired
handler.on('mousedown', mousedownHandler);
handler.on('mousemove', mousemoveHandler);
function mousedownHandler (ze) {
checkingTarget = ze.target;
if (checkingTarget) {
const e = ze.event;
this._x = e.clientX;
this._y = e.clientY;
}
}
function mousemoveHandler (ze) {
// pan -> down & move the same target
if (!(checkingTarget && checkingTarget === ze.target)) {
return;
}
const e = ze.event;
const dx = e.deltaX = e.clientX - this._x;
const dy = e.deltaY = e.clientY - this._y;
if (Math.sqrt(dx * dx + dy * dy) < 1) {
return;
}
panningTarget = checkingTarget;
checkingTarget = null;
this._x = e.clientX;
this._y = e.clientY;
docHandlerProxy.on('mousemove', pan, handler);
docHandlerProxy.on('mouseup', panEnd, handler);
this.dispatchToElement(param(panningTarget), 'panstart', e);
}
// `e` comes from `document`, it's a native event obj
function pan (e) {
if (!panningTarget) {
return;
}
e.deltaX = e.clientX - this._x;
e.deltaY = e.clientY - this._y;
this._x = e.clientX;
this._y = e.clientY;
this.dispatchToElement(param(panningTarget), 'pan', e);
}
// native event obj
function panEnd (e) {
if (panningTarget) {
docHandlerProxy.off('mousemove', pan, handler);
docHandlerProxy.off('mouseup', panEnd, handler);
this.dispatchToElement(param(panningTarget), 'panend', e);
}
checkingTarget = panningTarget = null;
}
return function dispose () {
docHandlerProxy.dispose();
}
}
// usage:
const dispose = GestureMouse(zr.handler);
const rect = new Rect({
...
onpanstart: (e) => {},
onpan: (e) => {},
onpanend: (e) => {}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment