Last active
June 21, 2022 03:15
-
-
Save yuqianma/f4db109962dde8020084c46c6f89d5a5 to your computer and use it in GitHub Desktop.
zrender custom gesture pan. The element can be panned outside the canvas.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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