fabricjs-用户轨迹采集

背景

通过平板抄写公式、文字等

需求分析

  1. 一个抄写模板展示面板
    • 面板可拖动、缩放
    • 面板不可影响手势采集
  2. 实时轨迹
    • 实时可视化用户手指/笔在平板上的绘制轨迹
    • 通过手势绘制一个多边形来圈选轨迹集合
    • 可撤销上一条轨迹
  3. 轨迹图可缩放、拖动
  4. 背景网格
  5. 工具栏
    • 可折叠展开
    • 笔画可调整大小、颜色
    • 展示一些额外信息
    • 清空轨迹
    • 撤销上一条轨迹
  6. 可全屏
  7. 审核时,可附加审核数据

功能拆分

  1. toolBar:工具栏
  2. modelBar:模板bar
  3. EventProxy:事件代理层
  4. fabric:视图层
    • paintZone
  5. sider:侧边栏
  6. core:内核层,数据处理
  7. forbidenZone:禁止绘画bar

技术选型

涉及复杂轨迹的增删,canvas和svg都无法满足要求,需要一个封装几何元素、集管理、优化、抽象为一体的框架,开源库中有konva/fabricjs,fabricjs目前活跃度最高,所以技术选型为fabricjs。

架构设计

设计图如下 主要是将事件代理层解耦出来,做统一的代理、性能优化并分发

设计模式

  1. mvc:利用model层+react-hook的方式控制view层,即利用了react-hook的范围锁定、也高度放开了controller层的可操作性
  2. 订阅发布模式:将事件监听层剥离出来,以订阅发布的方式管理,解耦了事件监听层和事件处理层,提高了可维护性、可测试性。
  3. fabric
    • 工厂模式:大部分几何元素都通过一个工厂类来生成
    • 单例模式:全局唯一的canvas对象,方便共享变量,全局访问
    • 观察者模式:将事件触发和事件处理通过订阅发布的方式解耦
    • 命令模式:以遥控器里的各个按钮(命令)来控制电视机;fabricjs将用户的操作(创建元素、移动、旋转、缩放对象)命令化,从而能记录用户的行为并方便撤销行为
    • 适配者模式:对不同的浏览器做不同的适配操作

问题收集

性能问题

  • 圈选是实时的,即判断一个多边形是否相交于或包含于一条复杂轨迹,因为使用了射线法,当遇到大量轨迹的时候,可能会卡顿。目前做了多重优化手段,比如函数节流、先稀疏复杂轨迹的点、然后判断图形的占位区域是否相交、然后判断图形的线段之间是否相交、然后判断是否包含关系。
  • 轨迹的实时生成,在一长串touchmove事件中,使用一个初始化的polyline,后续更改其点集,这样只需要实例化一个对象,性能高。
  • touchmove回调里执行复杂的逻辑,这会阻塞touchmove的触发频率,我们将touchmove里的回调通过settimeout放到异步队列中,这样就剥离了touchmove事件层 和 回调函数处理层,这样touchmove的触发频率就不会被影响

禁止绘制区域

该需求无法实现,因为当我们手掌放在平板上时,会触发系统级别的误触识别算法,阻止所有的触摸事件,所以我们没办法在页面上实现该功能。

项目总结

最值得突出的两个点,

  1. 针对三个性能问题的优化
  2. 设计模式的添加,从fabricjs的设计模式中学到很多,比如工厂模式、单例模式、命令模式、观察者模式的应用
相关推荐
腾讯TNTWeb前端团队1 小时前
helux v5 发布了,像pinia一样优雅地管理你的react状态吧
前端·javascript·react.js
范文杰4 小时前
AI 时代如何更高效开发前端组件?21st.dev 给了一种答案
前端·ai编程
拉不动的猪4 小时前
刷刷题50(常见的js数据通信与渲染问题)
前端·javascript·面试
拉不动的猪5 小时前
JS多线程Webworks中的几种实战场景演示
前端·javascript·面试
FreeCultureBoy5 小时前
macOS 命令行 原生挂载 webdav 方法
前端
uhakadotcom6 小时前
Astro 框架:快速构建内容驱动型网站的利器
前端·javascript·面试
uhakadotcom6 小时前
了解Nest.js和Next.js:如何选择合适的框架
前端·javascript·面试
uhakadotcom6 小时前
React与Next.js:基础知识及应用场景
前端·面试·github
uhakadotcom6 小时前
Remix 框架:性能与易用性的完美结合
前端·javascript·面试
uhakadotcom6 小时前
Node.js 包管理器:npm vs pnpm
前端·javascript·面试