本文只是一个paper.js
的使用注意事项,可以算是踩坑指南,不是翻译文档,有问题可以留言交流。
最近在搞一个图形框选工具,支持矩形、椭圆、多边形框选,同时需要限定范围,写本篇目的是看国内中文资料很少,将这次踩坑指南记录一下,便于大家交流;具体操作为首先在一张图片框选一个范围作为限定范围,然后第二个人再次进行框选,只能在第一个人指定的方位框选,限定范围和框选范围均支持三种类型,如下图所示中间透明区域即为限定范围,绿色即为框选范围(图片来自网络)
fabric.js:这个框架支持鼠标进行矩形和椭圆形的框选以及变换,我尝试在这个框架的基础上进行多边形框选,以及限定范围的处理,发现本框架扩展较差,不太适合此场景
原生js:尝试原生,能很快的实现想要的功能,但是对于边界的检测,图形的交叉检测自己写有点费劲
paper.js,two.js:均为二维图形绘制库,对比了两个库github的star,以及示例,选择了paper.js
首先要注意的是,关于使用PaperScript
与js
调用他的api
的区别,我直接使用的js
来进行调用,主要需要注意的点如下(paperScript代码不放)
paper.setup(canvas)
或者new Project(canvas)
来创建一个空的project
和view
需要在元素加载完毕后,再创建paper project
,也就是需要
window.onload = function() { var canvas = document.getElementById('myCanvas'); paper.setup(canvas); }
关于工具,对于PaperScript
的工具使用则可以直接使用事件,使用js需要自己创建工具,如
var tool = new Tool(); var path; tool.onMouseDown = function(event) { path = new Path(); path.strokeColor = 'black'; path.add(event.point); } tool.onMouseDrag = function(event) { path.add(event.point); }
关于运算,很多官方示例给出的为+
,-
,*
,/
,实际上我们使用js操作会出现报错,此时我们应该采用向量的add
,subtract
,multiply
,divide
方法来进行代替,如下
var vector = point2 - point1; // paperScript写法 var vector = point2.subtract(point1); // js写法
参考链接:http://paperjs.org/tutorials/...
向量是这里边很重要的一个概念,理解了向量的概念对于绘图以及操作动画轨迹我认为是很重要的一个功能(具体可以看下方资料),此处我只说一点,就是Point
本身其实就是代表一个向量,如图
point1
和point2
均为向量,这个其实代表了他们的相对于远点也就是canvas左上角的向量值
如果我们想把point1
移动到point2
那么,其实首先向右移动60,然后向下移动50
那么此时我们有一个更简单的方法,就是通过向量
var vector = point2 - point1; // = { x: 110, y: 200 } - { x: 50, y: 50 } // = { x: 60, y: 150 }
这样做减法,我们就得到了一个向量,也就是说point1
和point2
是绝对位置,而vector
则为相对位置,通过这个方式我们得到了vector
,此时我们可以得到他的长度和角度,帮助我们完成一些必要的运算
console.log(vector.length); // 161.55494 console.log(vector.angle); // 68.19859
通过向量,我们则可以对点的位置进行操作和处理
参考中文资料:https://www.microheart.me/pap...
参考官网资料:http://paperjs.org/tutorials/...
存在图层的概念,类似于PS工具的层级关系
PaperScope1
project1(操作对象)
layer1(图层)
但是此处有几个点需要注意
paper.project
)中活跃的图层(project.activeLayer
)当中,如果需要设置,需要自己处理配置paper.settings.insertItems // 是否将新建的Item插入到活跃的图层中
size
属性,这个对于Shape
是有的,但是Path
没有,一定注意下图的Properties
的不同,避免踩坑
Project
后会默认加到全局的paper.projects
当中,并作为一个被激活的project
,如果存在多个project
,请处理处理多个project的活跃关系,避免出现想要往一个project里边加,但是却导致加到另外一个里边,激活一个对象的方法为(如果insertItems
为默认值true
,这个问题易出现)project.activate(); // 使用当前对象绘制图形
paper.js的工具就是处理鼠标和键盘事件,同时当实例化Tools
时会加入到全局,如果存在多个Tools
也应该注意,避免多个监听事件使用出现问题
var tool1 = new Tools(); var tool2 = new Tools(); tool1.onMouseUp = () => { console.log('tool2'); }; tool2.onMouseUp = () => { console.log('tool2'); }
tool1
和tool2
均会放在paper.tools
当中,同一时间只能有一个工具生效,也就是上面两个onMouseUp
同时只能有一个回调被使用到,激活某一个工具,如下
tool1.activate();
这个东西在图形处理的时候很有用,这里说一下官网支持的一些东西
点检测方法为hitTest
,示例为
project.hitTest(point[, options])
其中point
即为paper.js
实例化的一个点,比如new Point(15, 20)
则检测[15, 20]这个店是否命中了某个图形,命中的位置为什么,命中的对象结构参照HitResult
类
其中options
为一个对象,代表对检测的一些控制,下面列出一部分
paper.settings.hitTolerance
aPath
是否与bPath
相交,返回一个布尔值
aPath.intersects(bPath);
获取aPath
和bPath
相交的点,并返回相交的点集合
aPath.getIntersections(bPath)
canvas
原生的一些内容能够帮助更好的绘图,比如两次绘制之间关系(paperjs为blendMode
,原生为globalCompositeOperation
),参照:https://developer.mozilla.org...
ctx.clip()
,paper.js
为使用clipMask
属性),使用这个时候后续图形绘制的显示将仅能展示在此裁剪路径当中下面几个事件处理很有用,可以注意一下,可以看下方代码使用
removeOnUp()
在鼠标拖拽时,不断清空上一次的绘制,然后绘制一个新的,这样就能做出鼠标操作绘制出矩形和椭圆形的功能了
tools.onMouseDrag = (event) => { var path = new Path.Circle({ center: event.point, radius: 10, fillColor: 'black' }); path.removeOnDrag(); }
segment
段的方法,等待自己去探索使用paper.js
还有很多有意思的功能,只是需要注意上面的一些坑,虽然中文资料不多,但是逐步看看官方文档,慢慢也就能看懂了
官网API地址:http://paperjs.org/reference/...