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的设计模式中学到很多,比如工厂模式、单例模式、命令模式、观察者模式的应用
相关推荐
轻口味19 分钟前
【每日学点鸿蒙知识】AVCodec、SmartPerf工具、web组件加载、监听键盘的显示隐藏、Asset Store Kit
前端·华为·harmonyos
alikami22 分钟前
【若依】用 post 请求传 json 格式的数据下载文件
前端·javascript·json
wakangda1 小时前
React Native 集成原生Android功能
javascript·react native·react.js
吃杠碰小鸡1 小时前
lodash常用函数
前端·javascript
emoji1111111 小时前
前端对页面数据进行缓存
开发语言·前端·javascript
泰伦闲鱼1 小时前
nestjs:GET REQUEST 缓存问题
服务器·前端·缓存·node.js·nestjs
m0_748250031 小时前
Web 第一次作业 初探html 使用VSCode工具开发
前端·html
一个处女座的程序猿O(∩_∩)O1 小时前
vue3 如何使用 mounted
前端·javascript·vue.js
m0_748235951 小时前
web复习(三)
前端
AiFlutter1 小时前
Flutter-底部分享弹窗(showModalBottomSheet)
java·前端·flutter