以下剖析均采纳 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 中存在图形和画布, 以及画布做了分层。彼此存在事件先后 (冒泡) 程序。
最初
可视化相干的架构设计, 源码学习,日常开发。我会逐渐进行深刻分享。如果对你有帮忙请关注我后续的内容。有须要的同学能够加一下我的联系方式(在我的主页, 拉你进群聊)。