Paperjs 是一个较流行的 canvas 接口封装库,可以很方便的用来实现绘图功能,基本概念如下:
Geometry
Point, Size, Rectangle
Point:点,本质上是点的属性描述
1 2 3
| var myPt = new Point(10, 20)
|
Size:尺寸,用来表示宽度和高度
1 2
| var mySize = new Size(10, 20); console.log(mySize);
|
Rectangle:矩形,有多种实例化的方法(这些方法让我发现,其背后的实现原理很可能是使用数组来存储参数)
1 2 3 4 5 6 7 8 9 10 11
| var myPt = new Point(10, 20); var mySz = new Size(100, 200); var myRect = new Rectangle(myPt, mySz);
var myRect = new Rectangle(10, 20, 100, 200);
var myRect = new Rectangle(); myRect.point = new Point(10, 20); myRect.size = new Size(100, 200);
|
Vector
矢量是一个非常好用的东西,原因:
- 它不表示绝对坐标值,而是表示从起点到终点的相对坐标值;
- 相对坐标的特性,让矢量可以很方便用来做各种计算;
两个矢量可以相加,也可以相减,在几何层面,它们其实仅是方向的区别;
矢量与整数的乘法或除法,也很简单,即相对坐标放大或缩小指定的整数倍数,或者也可以理解为在极坐标中,不改变角度,仅改变矢量长度;
除了乘法外,也可以通过改变矢量的 length,实现相同的效果
1 2 3 4
| var newVec = oldVec * 3
newVec.length = oldVec.length * 3
|
矢量拥有角度 angle 属性,可以直接赋值,也可以对其进行计算
1 2 3 4 5 6 7
| var vec = new Vector(100, 100); console.log(vec.angle);
vec.angle = 135;
vec.angle = vec.angle + 90;
|
加减乘除、旋转等计算并不会改变旧的 vector 属性,而是会直接返回一个新的 vector;但当我们直接修改 vector 的属性时,则会改变 vector 的属性值;
Path
1 2 3 4 5 6 7 8 9 10 11
| var myPath = new Path();
myPath.add(new Point(0, 0)); myPath.add(new Point(100, 50));
myPath.add(new Point(0, 0), new Point(100, 50));
myPath.insert(1, new Point(30, 50));
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| var path = new Path(); path.strokeColor = "black"; path.add(new Point(30, 75)); path.add(new Point(30, 25)); path.add(new Point(80, 25)); path.add(new Point(80, 75)); path.closed = true;
path.fullySelected = true;
var copy = path.clone(); copy.fullySelected = true; copy.position.x += 100;
copy.smooth();
copy.remove();
|

1 2 3 4 5 6 7 8 9 10 11 12
| var circle = new Path.Circle(center_point, radius);
var path = new Path.Rectangle(point, size);
var rect = new Rectangle(new Point(50, 50), new Size(100, 100)); var path = new Path.Rectangle(rect);
var radius = new Size(20, 20); var path = new Path.Rectangle(rect, radius);
|

1 2 3 4
|
var triangle = new Path.RegularPolygon(new Point(80, 70), 3, 50); var decagon = new Path.RegularPolygon(new Point(200, 70), 10, 50)
|

样式
1 2 3 4 5
| var path = new Path({ segments: [[40, 115], [80, 180], [200, 20]], selected: true });
|

1 2 3 4
| path.strokeColor = "#ff0000";
path.strokeColor = new Color(0.5, 0, 0.5);
|

1 2
| path.fillColor = "#ff0000";
|


1 2
| path.storkeCap = "round";
|

1 2
| path.strokeJoin = "round";
|

1 2
| path.dashArray = [10, 12];
|

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| var firstPath = new Path.Circle({ center: [80, 50], radius: 35 });
firstPath.strokeColor = '#ff0000'; firstPath.fillColor = 'blue';
var secondPath = new Path.Circle({ center: [160, 50], radius: 35 });
secondPath.style = firstPath.style;
var newStyle = { strokeColor: "#ff0000", fillColor: "#000000", strokeWidth: 10, } path.style = newStyle;
|
1 2 3 4 5
| path.fillColor = null;
path.style = null
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| project.currentStyle = { strokeColor: "#000000" }
var firstPath = new Path.circle({ center: [100, 100], radius: 50, });
project.currentStyle.strokeWidth = 8; project.currentStyle.fillColor = 'green';
var secondPath = new Path.Circle({ center: [250, 100], radius: 50, });
|


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| var path = new Path.Circle({ center: [80, 50], radius: 35 });
path.selected = true;
var copy = path.clone(); copy.position.x += 150;
copy.flatten(4);
|

交互
有三个全局的鼠标事件,可以对鼠标操作进行响应,它们分别是
- onMouseDown
- onMouseDrag
- onMouse
鼠标事件的属性:
- point:当前鼠标位置
- downPoint:鼠标被按下时所在位置
- lastPoint:上一次鼠标事件的位置
- middlePoint:当前位置和上次位置的中点
- delta:当前位置和上次位置的矢量 vector(up 事件该值为按下和松开两个位置的矢量)
1 2 3 4 5 6 7 8 9 10 11 12 13
| var path = new Path(); path.strokeColor = "black";
function onMouseDown(e) { path.add(e.point); }
tool.minDistance = 20; tool.maxDistance = 20; tool.fixedDistance = 30;
|