静态网站设计怎么做,宏润建设集团股份有限公司网站,潍坊专业汽车贴膜,百度一下下载安装本文讲解开源白板工具 Excalidraw 的架构设计。 版本 0.16.1 技术栈
Vite React TypeScript Yarn Husky。
脚手架原来是用的是 Create React App#xff0c;但这个脚手架已经不维护了#xff0c;一年多没发布新版本了。
目前市面上比较流行的 React 脚手架是 Vite React TypeScript Yarn Husky。
脚手架原来是用的是 Create React App但这个脚手架已经不维护了一年多没发布新版本了。
目前市面上比较流行的 React 脚手架是 Vite所以几个月前 Excalidraw 把脚手架替换为了 Vite很合理。
使用了 React 去实现 UI 层国外还是 React 流行一些。
TypeScript 用于类型标注减少一些类型错误。
Yarn 是包管理器没有使用 monorepo。
Husky 是 git hook 库会在本地 git commit 做一些校验。
架构设计
模块耦合比较严重基本核心逻辑都放在 App 类组件里导致其所在的 App.tsx 文件行数达到 8000 行。
数据状态大多保存在 App 类组件的 state 属性中。 可以看到编辑器的内核和 UI 是强绑定的完完全全耦合在一起了。
如果你想把这个项目的 UI 层改成基于其他框架比如 Vue那基本是要重写了。
但一些复杂的方法也是会抽离出来放到一个单独的文件里比如 group.js 里放的都是和编组相关的逻辑但使用的是函数风格里面全是零散的函数没有使用面向对象的写法。
渲染方案
Excalidraw 选择了 Canvas 2D 渲染方案。
Canvas 2D 的优点是 API 做了高级封装对开发者非常友好缺点是其并不是为了高性能而设计的很多底层图形计算是基于 CPU不能很好地利用 GPU 的并行计算能力。
一句话就是性能较差但比 SVG 好。
图形库使用了开源库 rough一款基于 Canvas 2D 和 SVG 的手绘风图形库。
图形工具
this.state.activeTool.type 会记录当前使用的是哪个工具。
工具没有抽成类它们的逻辑混合写在鼠标事件响应函数 handleCanvasPointerDown、handleCanvasPointerMove、handleCanvasPointerUp 中。
完全耦合在一起了。
如果我来做我会抽一个工具管理类然后实现各种工具类把它们注册到工具管理类里。 这样写维护性非常差你要改某一个工具比如创建矩形的逻辑你不得不看其他工具的逻辑要从这一坨分支里面找到创建矩形操作会走的逻辑。
图形树
图形树的状态保存在 Scene 类中
nonDeletedElements一个拍平的图形元素数组elements历史创建的所有图形被删除的图形还能在这里找到。
有组的概念图形对象的 groupIds 数组属性表示当前元素在哪些组下。
渲染
渲染图形树的入口方法是 renderStaticScene。
会顺序递归图形树的图形将它们渲染出来。
没有使用脏矩形局部渲染。
图形拾取方案
图形拾取使用了几何法。
不同图形的的渲染逻辑的判断逻辑是写在一起的。
历史记录
历史记录的逻辑在 History 类中。
Excalidraw 维护了两棵树当图形树发生了变更时会对一一比两棵树中图形的版本号。
如果相同说明没发生变更不添加新的历史记录项否则就创建一个历史记录项。
被更新的图形会拷贝一份保存到 elementCache 里。
stateHistory 和 redoStack 记录的是整棵树的图形 id 和新的版本号撤销重做时会从中取出去更新对应的图形为指定的版本。
国际化方案
国际化代码在 i18n.ts 文件中。
使用了状态管理库 jotai去通知组件更新。
渲染性能优化
剔除 视口外的图形不渲染很基本的操作。
缓存 图形到手绘风是需要计算的Excalidraw 会把这个结果缓存下来如果只是几何属性的改变就能直接使用缓存可以减少计算量。
缩放进行防抖延迟图形树的重渲染。
滚动事件频率很高每一帧都重渲染对于图形很多的情况下Excalidraw 是吃不消的因为 Canvas 2D 性能并不高这时候可以考虑节流或防抖去减少重渲染的次数。
我们发现通过滚轮放大画布时Excalidraw 的图形是模糊的鼠标释放时才真正重渲染。
结尾
Excalidraw 作为一款白板工具功能很完善美中不足的地方就是代码写得太面条。
本文透析了 Excalidraw 在图形编辑器上几个比较基础但很重要的功能希望对你进行图形编辑器的架构有帮助。
我是前端西瓜哥欢迎关注我学习更多图形编辑器知识。