Konva事件机制

news2024/11/24 4:10:00

前言

不同于HTML或SVG标签可以直接绑定事件,Canvas是使用JavaScript来绘制内容,这意味着其内容没有具体的DOM,所以Canvas渲染引擎都会自己实现一套事件机制。Konva的事件机制支持图形的选中、拖拽等交互处理,同时还支持单个图形对象绑定对应的事件。Konva版本是v9.2.1。

Konva事件机制

Konva支持绑定的事件包括Mouse类事件、Touch类事件、Drag事件、Transform事件,具体事件可查看官网说明。使用下面的实例来说明Konva的事件机制:

      const stage = new Konva.Stage({
        container: 'root',
        width: window.innerWidth,
        height: window.innerHeight,
      });
      const layer = new Konva.Layer();
      const circle = new Konva.Circle({
        x: 230,
        y: 100,
        radius: 60,
        fill: 'red',
        stroke: 'black',
        strokeWidth: 4,
      });
      
      circle.on('click', () => {
        console.log('click circle');
      });

      stage.on('click', () => {
        console.log('click stage')
      })

      layer.add(circle)
      stage.add(layer)

上面案例实现对Circle以及Stage绑定点击事件,在Konva中事件实例方法都是Node基类提供的,相关方法如下:

  • on/addEventListener:注册事件
  • off/removeEventListener:解绑事件
  • fire/dispatchEvent:触发事件

主要关注事件的注册方法的逻辑,主要的处理逻辑如下:

on(evtStr, handler) {
  ...
  if (!this.eventListeners[baseEvent]) {
    this.eventListeners[baseEvent] = [];
  }
  this.eventListeners[baseEvent].push({
    name: name,
    handler: handler,
  });
}

每个继承自Node基类的容器类以及图形类的实例对象都使用eventListeners属性来保存事件以及处理程序,故而每个图形元素都可以注册事件。注册完成后如何触发呢?除了在代码层次调用fire触发事件的方式,就是界面交互触发。

事件响应

在之前Konva基本使用文章中实际上可知Stage类会构建内容节点并且作为事件接收层,content节点绑定的事件以及对应处理程序如下:

[
	[MOUSEENTER, '_pointerenter'],
    [MOUSEDOWN, '_pointerdown'],
    [MOUSEMOVE, '_pointermove'],
    [MOUSEUP, '_pointerup'],
    [MOUSELEAVE, '_pointerleave'],
    [TOUCHSTART, '_pointerdown'],
    [TOUCHMOVE, '_pointermove'],
    [TOUCHEND, '_pointerup'],
    [TOUCHCANCEL, '_pointercancel'],
    [MOUSEOVER, '_pointerover'],
    [WHEEL, '_wheel'],
    [CONTEXTMENU, '_contextmenu'],
    [POINTERDOWN, '_pointerdown'],
    [POINTERMOVE, '_pointermove'],
    [POINTERUP, '_pointerup'],
    [POINTERCANCEL, '_pointercancel'],
    [LOSTPOINTERCAPTURE, '_lostpointercapture']
]

click事件会触发_pointerdown、_pointerup,主要的处理逻辑总结如下:
click处理逻辑
从Stage Content DOM节点接收事件触发相关事件处理程序运行,相关的事件处理程序的逻辑简单概括就是如下两点:

  • 计算当前点击位置的相对Content节点的位置坐标:先计算Content DOM节点的偏移位置数据,相对Content的位置坐标 = 当前点击位置的屏幕坐标 - Content偏移位置
  • 根据位置坐标然后根据相关逻辑得到当前对应的Shape对象
  • 触发Shape的fireAndBubble实例方法,该方法内部会实现事件冒泡,即查找当前Shape是否存在父节点,只要存在父节点就会一直调用fire实例方法触发事件事件

通过上面的机制从而实现事件冒泡,并且Konva还提供listening属性来实现对应图形对象是否触发事件。

图形命中策略

在上小结事件响应中根据位置坐标找到对应的Shape对象这个逻辑并没有细说,实际上这部分逻辑非常重要,这里细细说明。实际上这部分的逻辑是在getIntersection实例方法中,该实例方法的核心逻辑如下图所示:
getIntersection实例方法
当根据位置选中图形对象就会遍历所有的Layers进行处理,最后调用的核心逻辑如下:

        _getIntersection(pos) {
            const ratio = this.hitCanvas.pixelRatio;
            const p = this.hitCanvas.context.getImageData(
            	Math.round(pos.x * ratio),
            	Math.round(pos.y * ratio),
            	1, 1
            ).data;
            const p3 = p[3];
            // fully opaque pixel
            if (p3 === 255) {
                const colorKey = Util._rgbToHex(p[0], p[1], p[2]);
                const shape = shapes[HASH + colorKey];
                if (shape) {
                    return {
                        shape: shape,
                    };
                }
            }
            ...
        }

从上面逻辑可以看出两点核心处理:

  • 会调用hitCanvas的getImageData,获取对应位置的图像像素值
  • 根据像素值查找shapes中对应的shape对象

hitCanvas实际上是在Layer构建实例时调用HitCanvas创建的Canvas层,而shapes的处理逻辑是对应Shape基类初始化时的逻辑,具体如下:

    class Shape extends Node {
        constructor(config) {
            super(config);
            // set colorKey
            let key;
            while (true) {
                key = Util.getRandomColor();
                if (key && !(key in shapes)) {
                    break;
                }
            }
            this.colorKey = key;
            shapes[key] = this;
        }
        ...
     }

所有继承自Shape的图形类都会执行上面逻辑,其会生成唯一的颜色值并且保存到shapes map中,而hitCanvas在SceneCanvas绘制对应图形的也会绘制相同的图形,只不过hitCanvas绘制的图形被填充的颜色是单一颜色,通过色值可以快速准确的定位对应坐标位置的图形对象。

总结

Konva实现的事件机制可以实现图形对象绑定事件,实际上所有继承自Node基类的类,都可以使用on等实例方法来监听对应事件。

整个的事件机制总结如下:

  • 在Stage实例化时生成使用Content节点,并且绑定相关事件到该节点上,对应事件处理程序就是Stage上相关实例方法

  • 当界面交互触发对应事件后,就会调用Stage对应的实例方法

    • 首先是根据鼠标点击位置的屏幕坐标以及Content节点位置计算出相对于Content的位置坐标
    • 然后使用getImageData得到位于内存中HitCanvas相应位置坐标下颜色值,根据颜色值在集合中查找是否有对应的Shape对象
    • 最后根据父子关系链递归触发事件,从而执行用户自定义的事件绑定处理程序,实现事件冒泡

Konva是通过在Layer实例化时增加一个HitCanvas来服务于后续图形命中逻辑,当绘制图形时会在SceneCanvas以及HitCanvas都绘制,只不过HitCanvas的图形绘制都会使用唯一色值填充,并将这个颜色值保存到集合中,这种方案可以很准确的处理复杂图形的选中,但是也存在相应的问题:

  1. 额外增加HitCanvas绘制图形,增大内存使用,并且每次图形更新都要额外处理HitCanvas
  2. 颜色值作为唯一键值,其大小是有限的,即255 * 255 * 255,当然这个数量级页面本身也会存在性能问题了

实际上目前对于Canvas图形拾取策略除了Konva这种色值法方案,还有几何计算法,具体的优缺点比较可以查看这篇文章
Canvas 的拾取方案选择。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1049050.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

微信小程序案例2-1:学生信息

文章目录 (二)准备图像素材(三)编写小程序页面结构 单击[确认] 清空页面结构文件index.wxml内容 修改页面配置文件index.json,不适用navigation-bar组件 删除全局配置文件app.json,删除渲染器配置&a…

一键开启默认打印机共享功能,如何用powershell编写一个一键开启windows本地默认打印机共享的脚本

环境: Win10 专业版 Win11专业版 powershell 问题描述: 一键开启默认打印机共享功能,如何用powershell编写一个一键开启windows本地默认打印机共享的脚本 解决方案: 修改Windows注册表来实现打印机共享:(未成功)打开注册表编辑器:按下Win + R组合键,输入"re…

手机,汽车大卖背后,华为生态进入发展新阶段

监制 | 何玺 排版 | 叶媛 从8月底至今,华为手机、汽车的热度就没有消退过。 如今的华为产品,从手机到AR眼镜,从智慧屏到汽车,几乎全线都处在一机难求、一车难求状态。 9月25日举行的华为秋季全场景新品发布会, 更是…

实验三十三、三端稳压器 LM7805 稳压性能的研究

一、题目 LM7805 输出电压、电压调整率、电流调整率以及输出纹波电压的研究。 二、仿真电路 电路如图1所示。集成稳压芯片采用 LM7805CT。 三、仿真内容 (1)测量图1(a)LM7805CT 的电压调整率,测量条件为 I O 50…

【数据结构与算法】通过双向链表和HashMap实现LRU缓存 详解

这个双向链表采用的是有伪头节点和伪尾节点的 与上一篇文章中单链表的实现不同,区别于在实例化这个链表时就初始化了的伪头节点和伪尾节点,并相互指向,在第一次添加节点时,不需要再考虑空指针指向问题了。 /*** 通过链表与HashMa…

算法与数据结构-Trie树

文章目录 什么是“Trie 树”?如何实现一棵 Trie 树?Trie 树真的很耗内存吗?Trie 树与散列表、红黑树的比较 什么是“Trie 树”? Trie 树,也叫“字典树”。顾名思义,它是一个树形结构。它是一种专门处理字符…

SolidWorks 入门笔记03:生成工程图和一键标注

默认情况下,SOLIDWORKS系统在工程图和零件或装配体三维模型之间提供全相关的功能,全相关意味着无论什么时候修改零件或装配体的三维模型,所有相关的工程视图将自动更新,以反映零件或装配体的形状和尺寸变化;反之&#…

软考高级之系统架构师之计算机基础

概述 今天是9月28日,距离软考高级只剩37天,加油! 概念 三种周期: Clock Cycle:时钟周期,CPU主频,又称为时钟频率,时钟周期是时钟频率的倒数Instruction Cycle:指令周…

人工智能 与 搜索引擎的较量

随着科技的不断进步,人工智能(AI)已经渗透到了我们生活的方方面面,搜索引擎也不例外。AI与传统搜索引擎之间的较量成为了科技界和互联网用户关注的热点话题。 人工智能 与 搜索引擎的较量 A - 搜索引擎B - 人工智能AI 的优势理解力…

感谢信 | 企企通赋能鲜丰水果搭建特色数字化供应链协同系统,领跑中国水果连锁品牌

近日,由企企通携手鲜丰水果股份有限公司(以下简称“鲜丰水果”)打造的一站式数字化采购供应链管理平台成功上线。 鲜丰水果项目顺利上线后,客户对企企通项目团队的努力付出作出了高度评价,并收到了来自鲜丰水果的感谢信…

Java中String转换为double类型

这次的java作业是写一个数字转换的小项目,其中从输入框中获取的是String类型,但是要进行数字操作,此时要用到很多操作String类型数据的方法了。 从javafx输入框中获取到String类型后,首先是要判断是否能转换为数字或者小数形式&a…

多线程 dispatch

51423 https://blog.csdn.net/yanhaijunyan/article/details/115083522

问题 - 谷歌浏览器 network 看不到接口请求解决方案

谷歌浏览器 -> 设置 -> 重置设置 -> 将设置还原为其默认值 查看接口情况,选择 All 或 Fetch/XHR,勾选 Has blocked cookies 即可 如果万一还不行,卸载浏览器重装。 参考:https://www.cnblogs.com/tully/p/16479528.html

WebGL 渲染三维图形作为纹理贴到另一个三维物体表面

目录 渲染到纹理 帧缓冲区对象和渲染缓冲区对象 帧缓冲区对象 帧缓冲区对象的结构 如何实现渲染到纹理 示例程序(FramebufferObject.js) 创建帧缓冲区对象(gl.createFramebuffer()) gl.createFra…

windows:批处理bat入门

文章目录 什么是BAT常用命令与语法help与/?titlecolormodeechopausecallremset/a/p gotostartifif errorlevel for普通用法for /l 用法for /d用法for /r用法for /f用法in (file)delims和tokensskipeolusebackq 变量扩展变量延迟 setlocalshiftdirrd(删除文件夹&…

云中网络的隔离GREVXLAN

底层的物理网络设备组成的网络我们称为 Underlay 网络,而用于虚拟机和云中的这些技术组成的网络称为 Overlay 网络,这是一种基于物理网络的虚拟化网络实现。 第一个技术是 GRE,全称 Generic Routing Encapsulation,它是一种 IP-o…

Xposed 替换Textview文案

Xposed 替换Textview文案 这篇主要写下替换Textview的文案,主要实现比如脱敏。 public class TextViewHook {private static final String TAG "TextViewHook";public static void hook(XC_LoadPackage.LoadPackageParam lpparam) {Log.i(TAG, "ho…

取得信息系统项目管理师证书,薪资待遇怎么样?

作为信息系统项目管理师,薪资待遇是大家关心的一个话题。在中国,信息系统项目管理师是一种相对新兴的职业,但随着信息化时代的到来,这个职业的需求也越来越大。那么,信息系统项目管理师的薪资待遇到底怎么样呢&#xf…

高防服务器给企业带来的优势有哪些?

高防服务器主要指的是能够提供给网络安全提供高防护的服务器,通过流量清洗、负载均衡等手段来抵御DDoS攻击、CC攻击这一类流量攻击,为企业提供了强大的数据保障,互联网时代数据安全是放在第一位的,数据泄漏的话不论对于企业还是对…

国庆周《Linux学习第二课》

Linux开篇指南针环境安装(第一课)-CSDN博客 Linux详细的环境安装介绍在上面 第一 环境准备过程 安装过程