前言
最近项目中需要用到图形编辑工具,综合考虑下使用了paperjs。感谢 @jackwang的文章二维绘图库-paper.js踩坑指南,避免了很多坑,当时在实战项目中依然发现到一些问题。
项目中使用paperjs完成了一个图形框选工具,支持矩形、多边形、多点、线、虚线工具,功能上有框选、编辑、标签、位移、边界约束、缩放、放大镜、辅助线等常用功能 。
paperjs层级关系
开始之前一定要熟悉paper的项目层次结构避免coding时无从下手!!!
- 项目初始化
paper.setup()
后,paperjs将自动创建一个active状态的project和子属性layer,而tool需要自行添加。 - 注意project和layer的激活,只有激活了当前项才会改变。
- group分组可有可无,可以直接将path、text、raster放到layer中(如果项目中创建的物体包含多个path、text,建议使用group以便集中统一管理)
raster
const raster = new paper.Raster({
// source: 'https://xxxxxx.jpg',
// source:`data:image/jpg;base64,xxxxxxxxxxxx`
// image: document.getElementById('img'),
// crossOrigin: 'anonymous',
visible: false,
name: 'raster',
onLoad: e => {},
onError: e => {},
});
source
: 这个参数可传入URL,也可以传入base64,base64格式一定要注意前面加上”data:image/jpg;base64“crossOrigin
: canvas对外链图片有跨域问题,如果提示’Access-Control-Allow-Originxxxxxxx‘可自行尝试.onLoad
: 最坑的一个!
多图切换:假设两张图片A、B,当切换图片时,每次都要调用new paper.Raster(),初次加载A可以通过onLoad参数获取到图片信息,这是我们切换到B图片依旧通过onLoad参数获取到图片信息,但是在切换到已加载过的A时onLoad会返回图片信息为null,通过查阅源码发现其根据complete判断是否加载过当前图片以节约性能。源码逻辑可见paper-full.js _setImage()
约5514行。
解决方案:通过 const raster = new paper.Raster({
的raster变量来读取信息visible
: (优化)多图切换是会出现短暂画布空白或图片尺寸瞬间变大的情况,这是因为画布默认加载出示图片大小,
解决方案:默认visible为false在onLoad
中重新计算图片大小后在恢复visible即可
point区域内检测
Rectangle、Path、等绘制图形需要加上fillColor才能进行区域内检测,
如果想要透明形状并且需要区域内检测,设置透明值即可item.fillColor.alpha = 0.0001;
检测点是否在图形范围内hitTest(point)
带有背景的文本
paperjs没有自带的文本背景功能需要自行添加
const text = new paper.PointText({
content: content,
});
const bg = new paper.Path.Rectangle({
point: text.bounds.point,
size: text.bounds.size,
fillColor: '#cccccc',
});
其他
获取选中的select索引
:获取当前点击手柄的索引 e.location.indexid、查找匹配
:不要使用item自带的id!,item.id在操作中很可能会自动变更,所有关联数据放到data中,查找使用LAYER.getItem({xxx: xxx})
clone复制
: clone后的item默认插入到激活的layer中,如果想要插入到其他位置,Hierarchy Operations下的api清空画布
:paper自带了清空画布api,但是文档未说明paper.remove();获取多个图形的bounds
:将多个item编组,获取编组的Group.bounds冒泡问题
:item绑定的事件可以使用e.stopPropagation();阻止叠加的item触发事件,但是tool工具不受影响快去获取
:给item设置名称(可重复),item.name = 'testName',
const testName = group.children['testName']
或
const { testName } = group.children
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。