以下剖析均采纳 Sigmajs 框架源码进行剖析,有趣味的同学能够去查看一下。 本文次要介绍下Canvas的事件机制,和一些设计思路。
图形事件,设计思路及实现介绍。
图形事件须要反对以下的内容:
- 反对各类事件类型
- 事件触发机制
- 事件抵触问题
事件类型
mouse
- mousedown
- mousemove
- mouseup
- mouseenter
- mouseleave
- dblclick
- contextmenu
- click
- wheel
- drag 基于mousedown move leave做二次开发.
- dragstart
- dragend
touch
- touchstart
- touchend
- touchcancel
- touchmove
事件触发机制
依据事件的触发源不同能够分为两种:
- 图形上触发
- Canvas上触发
所有事件均在Canvas的DOM事件触发根底上实现。
以click为例:
鼠标在画布上点击 触发Canvas DOM事件,而后与图形进行碰撞 如果有就是图形点击 没有就是画布点击。伪代码示例:
Canvas.addEventListener("click", function(){ // MouseCoords == CanvasCoords // getShapeAtPoint(Shapes,CanvasCoords) if(true){ // 如果碰撞到图形 this.emit("clickGraph",false); return } this.emit("clickCanvas",false); // }, false);
事件抵触问题
drag 和 click 的抵触
因为 canvas 是一个DOM节点, 不是每个图元作为DOM 对象能够辨认,所以无奈通过 dragable 设置图形是否能够拖拽,这时候应用触摸板时的点击和拖拽会抵触。
在应用 mousedown,mouseup 过程中进行模仿, 对于在两者之间断定挪动的间隔和时间差进行一个判断。
具体是Click还是drag事件。
click 和 dbclick的抵触
其实不算是抵触问题, 是对于dbclick的实现基于click那么就须要对click事件有一个解决,不便辨认。请看代码示例:
handleClick(e: MouseEvent): void { if (!this.enabled) return; this.clicks++; if (this.clicks === 2) { this.clicks = 0; if (typeof this.doubleClickTimeout === "number") { clearTimeout(this.doubleClickTimeout); this.doubleClickTimeout = null; } return this.handleDoubleClick(e); } setTimeout(() => { this.clicks = 0; this.doubleClickTimeout = null; }, DOUBLE_CLICK_TIMEOUT); if (this.draggedEvents < DRAGGED_EVENTS_TOLERANCE) this.emit("click", getMouseCoords(e, this.container)); }
其余
对于事件的冒泡, 在Sigma中存在图形和画布,以及画布做了分层。彼此存在事件先后(冒泡)程序。
最初
可视化相干的架构设计,源码学习,日常开发。我会逐渐进行深刻分享。如果对你有帮忙请关注我后续的内容。有须要的同学能够加一下我的联系方式(在我的主页,拉你进群聊)。