事件代理功能点分享
看过前面几篇文章的读者相信也应该有所了解了,我们借助于团队内部开发的编辑器实现了很多成功的项目案例,已经多次看到我们点击一个文本、一个按钮等等...去弹出一个表格之类的交互,有些同学难免有些好奇我们是如何实现在 canvas 图形对象上实现事件派发和监听的,接下来听我娓娓道来。
准备工作
其实在实现事件代理对象之前,我实现过一个文本对象,就是在 canvas 上绘制出一个固定默认宽高的矩形,用户双击时可输入文字,它的实现可谓是非常简单。但是其中也有不容忽视的小细节需要注意。
文本对象的实现
双击文本对象时,实现一个临时的 DOM 节点
代码语言:txt复制 // 创建input
createTextInput() {
this.setVisible(false)
const textInput = document.createElement("input")
this.c("textInput", textInput)
// 设置基本样式
...
//input刚创建出来并不会自动聚焦
//这里需要调用一次自身focus 让input聚焦
textInput.focus()
const remove = () => {
// 删除Input
this.removeTextInput()
textInput.removeEventListener("blur", remove, false)
}
textInput.addEventListener("blur", remove, false)
}
// 更新input的位置
updateTextInput() {
this.setVisible(false)
const textInput = this.getClient("textInput")
const style = textInput.style
const zoom = this._network.getZoom()
const rect = this._network.getViewRect()
const { x, y } = this.getLocation()
style.display = "block"
style.left = x * zoom -rect.x "px"
style.top = y * zoom -rect.y "px"
}
记录并存储用户键入的内容和操作
这一步由于我们采用的是 input 所以我们只需要在 input 失去焦点的时候,获取到 input.value 的内容就行,同时也一定要注意要删除掉 input 节点,否则页面上的文本一旦多了起来,会很大程度影响性能.
- 监听用户离开,不再操作临时 DOM 节点,将键入的内容缓存取出设置到 文本对象上
- 在 UI 绘制中控制 canvas 绘制用户输入的内容
- 扩展部分: 暴露出部分可控的接口和方法在外部,用户可在属性面板配置操作轻松实现文字阴影、跑马灯、渐变色...等各种功能事件代理对象由此想到了我们是不是也可以实现一个类似的事件代理对象,这样一来我们就能轻松操作我们框架上 canvas 画布里的各种对象了。接下来就让我们一起去瞧瞧团队里是如何实现的事件代理对象。用什么实现代理使用虚拟的一个 HTMLNODE 节点代理目标对象事件
// BaseHTMLNode是自己封装的一个原生DOM节点对象
class EventProxyNode extends BaseHTMLNode {
constructor(network) {
// 关联的目标对象
this._attacher = null;
}
...
}
设计的时候要考虑到使用时传入一个目标对象关联绑定
关联目标对象
在这里我们通过绑定事件和派发事件去使得目标对象和代理对象关联
在编辑器中已经预留了派发事件和监听事件的操作面板。
在工具中步骤截图如下:
- 打开事件代理开关image.png
- 在目标对象上派发一个事件 配置派发的事件 image.png
- 然后在监听对象绑定监听事件并且写上处理逻辑,例如跳转切换等等...
由于我们在画布交互对象中注册了交互事件监听,每当我们的事件代理对象触发事件时就派发
一个画布的事件出去
- 预览效果
(不知道是哪位小伙伴写的注释,给他点赞