前言
最近我的项目中须要用到图形编辑工具,综合思考下应用了 paperjs。感激 @jackwang 的文章二维绘图库 -paper.js 踩坑指南,防止了很多坑,过后在实战我的项目中仍然发现到一些问题。
我的项目中应用 paperjs 实现了一个图形框选工具,反对矩形、多边形、多点、线、虚线工具,性能上有框选、编辑、标签、位移、边界束缚、缩放、放大镜、辅助线等罕用性能。
paperjs 层级关系
开始之前肯定要相熟 paper 的我的项目层次结构防止 codeing 时无从下手!!!
- 我的项目初始化
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