fabric.js实战
一、业务需求
- 给定一个图片作为参考
- 可配置画笔颜色、粗细
- 可通过手势生成实际轨迹
- 可通过手势来圈选轨迹
- 可撤销、删除轨迹
- 可操作轨迹
- 可缩放、拖动
- 背景网格,且背景网格可缩放和拖动
- 参考图片可缩放、偏移
- 手势处理系统,单指绘制、双指缩放、三指拖动
- 需要一个禁止绘制区域,方便用户在平板上有手掌的支撑区域
二、技术选型
因为涉及到轨迹
、操作轨迹
两点,
svg无法满足大量且复杂的轨迹,canvas没法操作轨迹,所以从 fabricjs/konva 中选型,
因 fabricjs 使用人数更多,所以采取了其作为技术选型。
三、fabric 原理
- 通过其内置的几何对象来创建图形
- 维护一个对象树
- 将对象树通过 canvas-api 绘制在实际的 canvas 上
因此,fabric 能做非常多的优化手段
- 已渲染的节点可通过
子canvas
做缓存 - 对比新旧对象树能做差值更新
- 虚拟画布,类似于虚拟滚动,只渲染可视化的区域
四、模块拆分
- header:与业务相关
- toolBar:工具栏
- sidebar:与业务相关
- canvas:绘制画板
五、架构设计
六、问题收集
6.1 性能问题
- 圈选是实时的,即判断一个多边形是否相交于或包含于一条复杂轨迹,因为使用了射线法,当遇到大量轨迹的时候,可能会卡顿。目前做了多重优化手段,比如函数节流、先稀疏复杂轨迹的点、然后判断图形的占位区域是否相交、然后判断图形的线段之间是否相交、然后判断是否包含关系。
- 轨迹的实时生成,在一长串touchmove事件中,使用一个初始化的polyline,后续更改其点集,这样只需要实例化一个对象,性能高。
- touchmove回调里执行复杂的逻辑,这会阻塞touchmove的触发频率,我们将touchmove里的回调通过settimeout放到异步队列中,这样就剥离了touchmove
事件层
和 回调函数处理层
,这样touchmove的触发频率就不会被影响
6.2 禁止绘制区域
该需求无法实现,因为当我们手掌放在平板上时,会触发系统级别的误触识别算法,阻止所有的触摸事件,所以我们没办法在页面上实现该功能。
touch事件
一个屏幕上可以有多个touch触摸点,这些触摸点绑定的target是可以多个的
touchEvent对象有如下重要属性
- targetTouches:只在当前target(比如某div)上触发的touch触摸点
- touches:在屏幕上触发的所有touch触目点
特别注意点:
- 没有类似鼠标的mouseout事件,所以你一开始是点在div上的,然后移出div的范围后,依旧触发touchmove事件
平板调试手段-chrome浏览器
- 平板安装chrome移动版
- 电脑安装chrome + chrome插件:inspect devices
- 平板开启开发者选项,然后允许usb调试
- usb链接平板和chrome
- 平板和电脑都打开chrome
- 电脑启动插件,然后就能控制平板的chrome,并且对该chrome访问的网页进行调试
- 很好用哇
作者:GambleMeow
来源:juejin.cn/post/7278931998650744869
来源:juejin.cn/post/7278931998650744869