SVG编辑器开发碎碎念

我的正在开发中的 svg 编辑器个人项目:https://github.com/F-star/svg-editor ,欢迎 star。

本文是关于 SVG编辑器 开发中涉及到的一些知识点。

知识点

  • 锁定元素(使元素不可操作),可以使用样式 pointer-events: none;。此外辅助线(如选区)也可以使用该样式,防止误触。

  • 使用样式 pointer-events: all; 后,即使一个元素的填充为 none,也能被选中。缺点是导致鼠标无法穿透,而导致其后面的元素无法被选中。

  • 使用 <svg> 的 viewBox 属性, 可以实现画布缩放效果。

  • <image> 元素设置宽高,图片仍会保持原宽高比,并尽可能贴合设置的宽高对应的容器。

  • 鼠标移动事件和释放事件需要绑定到 window 上。这样即使鼠标离开了 SVG编辑器视口,鼠标事件依旧能触发,实现 鼠标 按下->移动->释放 的操作闭环。如果你把鼠标事件放到 SVG 标签上,如果鼠标释放不是在 SVG 内,就会出现问题。

  • btoa方法支持成 ascii 码,不支持 utf8 的中文,需要对 utf8 转码: image.src = "data:image/svg+xml;base64," + btoa(unescape(encodeURIComponent(src)));

  • 浏览器中,只设置 strokestroke-width 会被默认设置为 1;相反如果只设置 stroke-widthstroke 会被默认设置为 #000。不能保证所有浏览器都这样实现,需要自行测试。

  • 推荐使用 typescript 进行开发。

  • 不要配合 vue 之类的 mvvm 框架做交互(比如拖拽vue实现的缩放条)。因为这些框架通过监控变量的变化触发方法,会导致某些方法会被多次执行。如果配合 vue,就需要做一些恶心的 hack。

jQuery、svg.js、paperjs、snapsvg。

svg.js

链式写法,有点类似 jQuery。优点是语法很清晰,封装地很好,用起来很方便。缺点是它的定位是快速的创建 SVG 元素,不是为了实现 SVG 编辑器而设计的。所以它的一些计算相关的 API 是没有的,比如求两个 path 的交点、布尔运算等方法都没有提供。

snapsvg

这个库是 Adobe 公司的开源库。Adobe 公司的 Illustrator 软件就是一款矢量图形编辑软件。snapsvg 确实可以拿来做编辑器,除了创建和修改元素一般 SVG 库都有的 方法,还提供了 SVG 编辑器需要用到的方法。比如将普通的 path 转为基于三阶贝塞尔的 path、计算path 上离某个点最近的点的坐标等方法。

这个库确实挺适合拿来做 SVG 编辑器,但却有一个问题,那就是这个库已经停止维护很长时间了。所以它如果有一些 bug,我们只能自己找出问题自己修复。

paperjs

paperjs 是一个 canvas 库。虽然它不是一个 svg 库,但它提供了 SVG 和 Canvas 互相转换的方法。这个库的强大之处,在于它提供了一些对 svg 编辑器非常有帮助的方法。该库提供了将折线转为曲线的方法、判断一个 path 是顺时针还是逆时针、以及最为强大的布尔运算方法!boxy-svg是一款基于 Web 的商业 svg 软件,它就使用了 paperjs 实现了布尔运算功能。

jQuery

作为一款优秀的操作 DOM 的库,是挺适合开发 Web 编辑器的。