paper.js的學(xué)習(xí)記錄,參考原英文教程
一.開始使用
1.1 paper.js的使用方式
2種渤刃,PaperScript 或者 JavaScript
1.2 直接使用JavaScript
1.2.1 Paper.js Architecture
scope登渣,projects, views, item,
,path(相當(dāng)于畫筆,可以畫point,矩形始绍,圓形,線段等等), size.
1.2.2 Setting Up a Scope
步驟:
1.關(guān)聯(lián)canvas元素
2.創(chuàng)建project和view: paper.setup("canvas id");
3.設(shè)置path: var path=new paper.Path();
4. 繪制: paper.view.draw();
eg:
<head>
<script type="text/javascript">
window.onload = function(){
var canvas = document.getElementById('myCanvas');
//通過setup創(chuàng)建一個(gè)空的project同時(shí)為這個(gè)canvas創(chuàng)建一個(gè)view兩種方式
//1. paper.setup(canvas);
//2. 使用id
paper.setup("myCanvas");
//創(chuàng)建一個(gè)Paper.js的path來在該canvas上畫一條直線
var path = new paper.Path();
//給這個(gè)直線設(shè)置顏色屬性
path.strokeColor = 'black';
//設(shè)置直線的起始點(diǎn)
var startPoint =new paper.Point(100,100);
var endPoint = startPoint.add([200,-50]);
path.moveTo(startPoint);
path.lineTo(endPoint);
//繪制
paper.view.draw();
}
</script>
</head>
<body>
<canvas id="myCanvas" resize></canvas>
</body>
1.2.3 Making the Scope Global
paper全局注入的兩種方式:
paper.install(window);
with (paper) { var path = new Path(); path.strokeColor = 'black'; var start = new Point(100, 100); //不需要再使用new paper.Point(100,100) path.moveTo(start); path.lineTo(start.add([ 200, -50 ])); view.draw(); } ```
1.2.4 Installing Event Handlers
總共有10種handler话侄,包括8個(gè)鼠標(biāo)handler和1個(gè)動畫handler和1個(gè)view resize時(shí)的handler
- onFrame(http://paperjs.org/reference/view/#onframe)
使用onFrame時(shí)亏推,自動實(shí)現(xiàn)view.draw()方法。 - onResize (http://paperjs.org/reference/view/#onresize)
原網(wǎng)站上的例子問題:
不知道為什么canvas的長寬一直被設(shè)置為304 X 154. 使用F12不斷打開和關(guān)閉窗口年堆,canvas大小會不斷變大吞杭,刷新后又回到最初狀態(tài)
canvas默認(rèn)大小304 X 154.補(bǔ)充canvas知識:https://www.cnblogs.com/JamKong/p/4987163.html
1.2.5 Working with Tools
問題 :Tools和Handlers的區(qū)別?
The global tool variable only exists in scripts that contain mouse handler functions (onMouseMove,onMouseDown,onMouseDrag,onMouseUp) or a keyboard handler function (onKeyDown,onKeyUp). 單只有handler可以被path調(diào)用变丧。
Tool()與handler連用
var tool = new Tool();
var path = new Path();
tool.onMouseDown = function(event){
path.strokeColor = 'black';
path.add(event.point);
}
tool.onMouseDrag = function(event){
path.add(event.point);
}
1.2.6 Multiple Tools
<script type="text/javascript">
paper.install(window);
var tool1,tool2;
window.onload = function(){
// var canvas = document.getElementById('myCanvas');
//通過setup創(chuàng)建一個(gè)空的project同時(shí)為這個(gè)canvas創(chuàng)建一個(gè)view兩種方式
//1. paper.setup(canvas);
//2. 使用id
paper.setup("myCanvas");
//path 的聲明放在外面芽狗,點(diǎn)擊是=時(shí)回與之前的點(diǎn)鏈接起來。放在mousedown函數(shù)里就不會有首尾鏈接痒蓬。但點(diǎn)擊鼠標(biāo)不會有畫點(diǎn)
// var path = new Path();
var path;
function mousedown(event){
path = new Path();
path.strokeColor = 'red';
//相當(dāng)于定義一個(gè)起點(diǎn)畫筆動作童擎。如果注釋掉這一行畫云操作會出錯(cuò)。
path.add(event.point);
}
tool1 = new Tool();
tool1.onMouseDown = mousedown;
// tool1.onMouseDown = function(event){
// path.strokeColor = 'black';
// path.add(event.point);
// };
tool1.onMouseDrag = function(event){
path.add(event.point);
};
tool2 = new Tool();
tool2.minDistance = 20;
tool2.onMouseDown = mousedown;
tool2.onMouseDrag = function(event){
path.arcTo(event.point);
}
}
</script>
<body>
<!-- too1,tool2要為全局變量 -->
<a href="#" onclick="tool1.activate();">lines</a>
<a href="#" onclick="tool2.activate();">clouds</a>
<canvas id="myCanvas" resize style="width:500px; height:500px;border:1px solid black"></canvas>
</body>
二. Geometry(幾何)
2.1 Point,Size and Rectangle
在paper.js中攻晒, 像Point顾复,Size 和Rectangle都是用來描述圖像幾何屬性的對象。他們抽象的代表了一些幾何特征鲁捏,例如位置和尺寸芯砸。但是他們并不直接表示一個(gè)帶有project的圖像{?a graphical item within a project}碴萧。
注意:
在paper.js中圖像出現(xiàn)在層列表中(layer list)乙嘀,在project中可見。類比于現(xiàn)實(shí)世界中的物理物質(zhì)破喻。為了描述它們的位置和大小虎谢,Paper.js 有不同的基礎(chǔ)類型。這些基礎(chǔ)類型僅僅是包含了描述圖像幾何特征的數(shù)值曹质。
這意味著當(dāng)我們在代碼中新建了一個(gè)Point時(shí)婴噩,實(shí)際上只是在view中創(chuàng)建了一個(gè)位置的描述,但是并沒有創(chuàng)建一個(gè)包含這個(gè)point的path來作為一個(gè)segment羽德。
var myPoint = new Point(10, 20);
console.log(myPoint); // { x: 10, y: 20 }
為創(chuàng)建一個(gè)把包含point作為segment的path几莽,需要明確地使用new Path()構(gòu)造器來創(chuàng)建一個(gè)path同時(shí)添加point作為這個(gè)path的第一個(gè)segment。
更多paths和segments的細(xì)節(jié)
http://paperjs.org/tutorials/paths/working-with-path-items/
var myPath = new Path();
myPath.add(myPoint);
運(yùn)行這一段腳本會在Paper.js的project中產(chǎn)生一個(gè)“物理”path宅静,這個(gè)path子在myPoint的位置有一個(gè)segment章蚣。
注意:
這里myPath的segment和點(diǎn)myPoint不是一樣的,myPoint只是簡單描述用來產(chǎn)生myPath第一個(gè)segment的坐標(biāo)姨夹。在segment創(chuàng)建之后改變myPoint segment不會再改變(纤垂?)矾策。
2.1.1 Point
Point對象描述一個(gè)二維坐標(biāo)。它有2個(gè)屬性x峭沦,y贾虽。代表位置的x軸和y軸。
可以直接提供x吼鱼、y的值來創(chuàng)建Point對象蓬豁,也可以不指定xy值,默認(rèn)為0. x,y可以分別賦值和改變菇肃。
point的兩種復(fù)制方式地粪,secondPoint改變了firstPoint不會改變:
1.
var firstPoint = new Point(20, 40);
var secondPoint = new Point(firstPoint);
2.
var firstPoint = new Point(20, 40);
var secondPoint = firstPoint.clone();
注意:下面這種方式不是克隆,改變2時(shí)1也會改變巷送。
var firstPoint = new Point(20, 40);
var secondPoint = firstPoint;
除了直角坐標(biāo)也可以用極坐標(biāo)表示驶忌。angel和length
2.1.2 Size
Size對象在二維空間描述抽象的尺寸矛辕。2個(gè)屬性width和height笑跛。
和Point對象類似,Size的創(chuàng)建方式也有2種:1.直接給width和height賦值聊品,或者不賦值飞蹂,,默認(rèn)為0翻屈。 width和height可以分開賦值和獲取陈哑。width和height的賦值可以是point的值、數(shù)組伸眶、對象惊窖。加減乘除操作。
2.1.3 Rectangle
[Rectangle(http://paperjs.org/reference/rectangle)
對象可以看做Point和Size對象的聯(lián)合厘贼,描述了2維的位置和尺寸界酒。因此它包含4個(gè)屬性:x,y,width,height. x和y描述矩形左上角的點(diǎn)嘴秸,width和height是尺寸毁欣。此外,還有point和size屬性岳掐,使用Point和Size來獲得凭疮。
Rectangle對象可以有多種方式來創(chuàng)建,一種是傳入一個(gè)Point和Size對象給new Rectangle(point, size)串述,或Rectangle(x,y,width,height)或是Rectangle(point1执解,point2)
2.2 Object Conversion
可以自由轉(zhuǎn)換參數(shù),所有的基礎(chǔ)類型可以自由的描述為數(shù)組或這js對象纲酗。
2.3 Mathematical Operations
Paper.js允許基本數(shù)據(jù)類型之間使用代數(shù)操作衰腌,Point和Size可以使用數(shù)字或這其它point和Size進(jìn)行加減乘除操作。
// Define a point to start with
var point1 = new Point(10, 20);
// Create a second point that is 4 times the first one.
// This is the same as creating a new point with x and y
// of point1 multiplied by 4:
var point2 = point1 * 4;
console.log(point2); // { x: 40, y: 80 }
// Now we calculate the difference between the two.
var point3 = point2 - point1;
console.log(point3); // { x: 30, y: 60 }
// Create yet another point, with a numeric value added to point3:
var point4 = point3 + 30;
console.log(point4); // { x: 60, y: 90 }
// How about a third of that?
var point5 = point4 / 3;
console.log(point5); // { x: 20, y: 30 }
// Multiplying two points with each other multiplies each
// coordinate seperately
var point6 = point5 * new Point(3, 2);
console.log(point6); // { x: 60, y: 60 }
對象轉(zhuǎn)換:
var point1 = new Point(10, 20);
var point2 = point1 + { x: 100, y: 100 };
console.log(point2); // { x: 110, y: 120 }
// Adding size objects to points work too,
// forcing them to be converted to a point first
var point3 = point2 + new Size(50, 100);
console.log(point3); // { x: 160, y: 220 }
// And using the object notation for size works just as well:
var point4 = point3 + { width: 40, height: 80 };
console.log(point4); // { x: 200, y: 300 }
// How about adding a point in array notation instead?
var point5 = point4 + [100, 0];
console.log(point5); // { x: 300, y: 300 }
2.3.1 Math Functions
point和Size四舍五入的方法:round(),ceil().floor();
2.3.2 Random Values
創(chuàng)建一個(gè)隨機(jī)值Point.random(); Size.random();
// Create a point whose x is between 0 and 50,
// and y is between 0 and 100
var point = new Point(50, 100) * Point.random();
// Create a size whose width is between 0 and 50,
// and height is between 0 and 100
var size = new Size(50, 100) * Size.random();
2.4 Vector Geometry 向量幾何
Vector Geometry是paper.js的頭等公民熊咽。在學(xué)習(xí)編寫腳本時(shí)衫仑,了解它的基本原理是一個(gè)很大的優(yōu)勢瞄崇。畢竟摹蘑,矢量圖形中的單詞矢量是有原因的。
下面是一個(gè)向量幾何的優(yōu)美的例子,下面是一個(gè)畫筆的例子凌埂,只有24行的代碼,它提供了一個(gè)像畫筆動作一樣的鼠標(biāo)操作丛晌,根據(jù)速度畫筆可變厚度,擁有自然的表達(dá)感屯吊。
tool.minDistance = 10;
tool.maxDistance = 45;
var path;
function onMouseDown(event) {
path = new Path();
path.fillColor = new Color({ hue: Math.random() * 360, saturation: 1, brightness: 1 });
path.add(event.point);
}
function onMouseDrag(event) {
var step = event.delta / 2;
step.angle += 90;
var top = event.middlePoint + step;
var bottom = event.middlePoint - step;
path.add(top);
path.insert(0, bottom);
path.smooth();
}
function onMouseUp(event) {
path.add(event.point);
path.closed = true;
path.smooth();
}
上段代碼畫圖筆刷的問題:step為NAN型虹蓄。
上段代碼會在Working with Mouse Vectors 只一步步解釋犀呼,但是 再看這個(gè)例子之前,先理解向量幾何是非常重要的外臂。
<a name="points-and-vectors" title="Points and Vectors" class="anchor"></a>
2.4.1 Point and Vector
在很多方面玛荞,vector和point很相似。都在直角坐標(biāo)系中勋眯,但point描述位置塞蹭,vector表示相關(guān)信息:從一個(gè)點(diǎn)到另一個(gè)的路徑。下面將逐步解釋vectors和points讶坯。
首先使用Point對象創(chuàng)建2個(gè)點(diǎn)番电,描述文檔中的絕對位置。
var point1 = new Point(50,50);
var point2 = new Point(110,200);
從點(diǎn)1到點(diǎn)2,相當(dāng)于在x軸方向上右移60辆琅,y軸方向下移150. point1減去point2得到值x,y
var x = point2.x - point1.x;
// = 110 - 50 = 60
var y = point2.y - point1.y;
// = 200 - 50 = 150;
使用向量來表示這2個(gè)分開的值更容易漱办,使用point 直接相減得到向量值:
var vector = point2 - point1;
// = { x: 110, y: 200 } - { x: 50, y: 50 }
// = { x: 60, y: 150 }
注意:
Mathematical Operations tutorial.中有更多算術(shù)操作
需要注意的是代碼中相減的結(jié)果(向量)仍然是一個(gè)point對象,嚴(yán)格來說婉烟,point和vector沒有區(qū)別娩井,只是point表示絕對位置, vector表示相對位置隅很。
向量也可以被描述成箭頭(array)撞牢。與箭頭相似率碾,向量指向特定的方向,同時(shí)指明在這個(gè)方向上移動的長度屋彪。因此常使用angle和length來描述向量所宰。
Point的對象有2個(gè)屬性:point.angel和point.length⌒蠡樱可以分別修改仔粥。
console.log(vector.length);
// 161.55494
console.log(vector.angle);
// 68.19859
默認(rèn)角度使用度數(shù)來表示
向量的簡單使用是把它添加到一個(gè)絕對位置點(diǎn)上。結(jié)果仍然是一個(gè)絕對點(diǎn)蟹但。我們可以把一個(gè)向量值加到不同的點(diǎn)上躯泰。下圖中我們看到的向量都是相同的恩但是因?yàn)槠鹗键c(diǎn)不同結(jié)果都不同。
2.4.2 Calculating with Vectors
2.4.3 Vector Addition and Subtraction
向量可以相加华糖,結(jié)果等同于從1個(gè)位置到另一個(gè)位置的2步操作麦向,結(jié)果是第三個(gè)向量。
首先有4個(gè)點(diǎn):
var point1 = new Point(50, 0);
var point2 = new Point(40, 100);
var point3 = new Point(5, 135);
var point4 = new Point(75, 170);
兩兩相減得到2個(gè)向量:
var vector1 = point2 - point1;
// = { x: 40, y: 100 } - { x: 50, y: 0 }
// = { x: -10, y: 100 }
var vector2 = point4 - point3;
// = { x: 75, y: 170 } - { x: 5, y: 135 }
// = { x: 70, y: 35 }
從startPoint開始客叉,首先加上vector1诵竭, 重新得到一個(gè)tempPoint。然后再加上vector2得到目標(biāo)點(diǎn)endPoint.
var tempPoint = startPoint + vector1;
var endPoint = tempPoint + vector2;
但是這樣分開加有點(diǎn)復(fù)雜.我們可以直接取兼搏,2個(gè)向量相加的結(jié)果卵慰。
var vector = vector1 + vector2;
向量相加是頭+尾。向量相減表示頭+相反方向的尾佛呻。
var vector = vector1 - vector2;
注意:
向量相加減的操作等同于向量xy坐標(biāo)加減裳朋,但是角度和長度加減無效。
2.4.3 向量的乘除
向量的乘除不改變方向吓著,只改變長度鲤嫡。
var bigVector = smallVector * 3;
注意:js限制,需要將向量值放在操作符左邊夜矗。因?yàn)樽筮叾x了返回類型泛范。因次這樣寫會出錯(cuò)。
var bigVector = 3 * smallVector;//錯(cuò)誤寫法
2.4.4 改變向量長度
除了乘除改變向量的長度紊撕,還可以直接改變vector的length屬性。
首先使用Point構(gòu)造器創(chuàng)建一個(gè)vector. vector和point是一種類型赡突。
var vector = new Point(24, 60);
console.log(vector.length);
// 64.62198 .長度計(jì)算方法60的平法+24的平方对扶,開根號
下面改變向量的length屬性。這與之前乘法的例子l類似惭缰,但這里是直接操作對象:
vector.length = vector.length * 3;
console.log(vector.length);
// 193.86593
也可以直接設(shè)置length的值
vector.length = 100;
使用point.normalize()也可以改變向量的長度浪南。歸一化一個(gè)向量是指將它的長度設(shè)為1.也可以自定義為別的數(shù)字。
var vector = new Point(24,60);
var normalizedVector = vector.normalize();
console.log(vector.length);
//64.62198
console.log(normalizedVector.length);
// 1
注意此時(shí)normalizedVector的長度值為1漱受,原始vector不變络凿。normalize()返回一個(gè)新的歸一化向量對象。
如果我們把向量標(biāo)準(zhǔn)化為10呢?
var normalizedVector = vector.normalize(10);
console.log(normalizedVector.length);
// 10
也可以這樣“
var normalizedVector = vector.normalize() * 10;
console.log(normalizedVector.length);
// 10
2.4.5 Rotating Vectors and Working with Angles
再創(chuàng)建path和shapes時(shí)旋轉(zhuǎn)向量非常有用絮记,它允許我們在某個(gè)特定角度定義一個(gè)相對方向來轉(zhuǎn)向另一個(gè)方向摔踱。在Working with Mouse Vectors有很好的演示例子。
rotated向量用來構(gòu)建與鼠標(biāo)移動并行的paths怨愤。
paper.js里的度數(shù):
-180度和180度在一個(gè)位置派敷。度數(shù)設(shè)置可以大于180度。
有2種方法來改變向量的角度:
- 設(shè)置vector.angle的值
var vector = new Point(100, 100);
console.log(vector.angle);
// 45
console.log(vector.length);
// 141.42136
vector.angle = 135;
console.log(vector.length);
// 141.42136
console.log(vector);
// { x: -100, y: 100 }
長度不變撰洗。
- 數(shù)值相加
vector.angle = vector.angle + 90;
//或
vector.angle += 90;
2.4.6 Operations, Methods and Properties
數(shù)學(xué)運(yùn)算(+篮愉、 - 、*差导、/)和數(shù)學(xué)方法rotate()和normalize()并不改變向量和點(diǎn)本身试躏。相反,它們返回一個(gè)新的對象设褐。這意味這他們可以在表達(dá)式中鏈接和組合颠蕴。
var point = event.middlePoint
+ event.delta.rotate(90);
相反,改變向量的angle和length會改變向量本身络断。因此裁替,我們在直接改變對象的值時(shí)需要特別小心,使用clone()方法貌笨,原始的對象就不會被改變弱判。
var delta = event.delta.clone();
delta.angle += 90;
var point = event.middlePoint + delta;
三. Path
3.1 Working with Path Items
3.1.1 Path Items 的剖析
paths由一系列由曲線連接的segments組成。一個(gè)segment由一個(gè)point和2個(gè)handlers組成锥惋,描述了segment的位置和曲線方向昌腰。
3.1.2 Adding and Inserting Segments
在這里我們使用目前未定義handlers的segments,因此由直線連接而不是曲線膀跌。
var myPath = new Path();
myPath.strokeColor = 'black';
myPath.add(new Point(0, 0));
myPath.add(new Point(100, 50));
add()也支持多個(gè)參數(shù)遭商。可以添加讀個(gè)segments捅伤。
var myPath = new Path();
myPath.strokeColor = 'black';
myPath.add(new Point(0, 0), new Point(100, 50));
插入segments到已有的segments中去劫流,使用path.insert(index,segment)方法:
var myPath = new Path();
myPath.strokeColor = 'black';
myPath.add(new Point(0, 0), new Point(100, 50));
// insert a segment between the two existing
// segments in the path:
myPath.insert(1, new Point(30, 40));
注意:
Point對象代表二維空間的一個(gè)點(diǎn),它并不是path中的一個(gè)錨點(diǎn)丛忆。當(dāng)Point作為參數(shù)傳入add()或insert()函數(shù)時(shí)祠汇,動態(tài)轉(zhuǎn)換為Segment類型。
3.1.3 Smoothing Paths
使用path.smooth()方法來自動平滑path。這個(gè)函數(shù)計(jì)算path的segment的handlers的最優(yōu)值來創(chuàng)建平滑的曲線。segments不移動當(dāng)前path的segments的handler設(shè)置忽略蒜田。
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;
// Select the path, so we can see its handles:
path.fullySelected = true;
// Create a copy of the path and move it 100pt to the right:
var copy = path.clone();
copy.fullySelected = true;
copy.position.x += 100;
// Smooth the segments of the copy:
copy.smooth();
3.1.4 Closing Path
默認(rèn)通過new Path()創(chuàng)建的paths是開放的:
var myPath = new Path();
myPath.strokeColor = 'black';
myPath.add(new Point(40, 90));
myPath.add(new Point(90, 40));
myPath.add(new Point(140, 90));
為封閉這個(gè)path,將path.closed屬性設(shè)為true后Paper.js 會自動連接第一個(gè)segment和最后一個(gè)segment我抠。
myPath.closed = true;
3.1.5 Removing Segments and Paths
從path中使用path.removeSegment(index)刪除segment苇本。index為segment索引地址,從0開始菜拓。
首先創(chuàng)建一個(gè)圈瓣窄。
var myCircle = new Path.Circle(new Point(100, 70), 50);
myCircle.strokeColor = 'black';
myCircle.selected = true;
有4個(gè)segment。刪除第一個(gè)segment:
myCircle.removeSegment(0);
整個(gè)刪除item.remove():
myCircle.remove();
3.2 Creating Predefined Shapes 創(chuàng)建預(yù)定義形狀
使用new Path()創(chuàng)建一個(gè)沒有點(diǎn)的空path尘惧。使用new Path.Circle(center,radius)和new Path.Rectangle(point,size)創(chuàng)建path時(shí)康栈,自動為其添加segments來創(chuàng)建預(yù)定義形狀。
3.2.1 Circle Shaped Paths 圓形
var myCircle = new Path.Circle(new Point(100, 70), 50);
myCircle.fillColor = 'black';
3.2.1 Rectangle Shaped Paths 矩形
創(chuàng)建矩形時(shí)可以傳入點(diǎn)也可以給new Path.Rectangle(rect)傳入rectangle喷橙。
注意:
一個(gè)Rectangle對象是一個(gè)矩形的抽象代表
例如:我們在(x:0,y:0)和(x:50,y:50)創(chuàng)建一個(gè)矩形啥么。使用new Path.Rectangle(rect)構(gòu)造器創(chuàng)建一個(gè)符合描述的形狀路徑。
var rectangle = new Rectangle(new Point(50, 50), new Point(150, 100));
var path = new Path.Rectangle(rectangle);
path.fillColor = '#e9e9ff';
path.selected = true;
3.2.2 Rectangle Shaped Paths with Rounder Corner 圓角矩形
new Path.RoundRectangle(rect,size);
文中new Path.RoundedRectangle(rect, size)報(bào)錯(cuò)贰逾。應(yīng)該不帶ed
var rectangle = new Rectangle(new Point(50, 50), new Point(150, 100));
var cornerSize = new Size(20, 20);
var path = new Path.RoundRectangle(rectangle, cornerSize);
path.fillColor = 'black';
3.2.3 Regular Polygon Shaped Paths規(guī)則的多邊形
使用new Path.RegularPolygon(center, numSides, radius)
center:中心點(diǎn)悬荣;
numSides:邊數(shù);
radius:半徑疙剑。
Path 所有的構(gòu)造器:Path reference
3.3 Using Color and Style
3.3.1 Example Path
下面例子中使用一個(gè)對號型路徑:
var myPath = new Path({
segments: [[40, 115], [80, 180], [200, 20]],
selected: true
});
3.3.1~7 Stroke Color
線條顏色及其它:
var myPath = new Path({
segments:[[40,115],[80,180],[200,20]],
//selected : true
});
//線條顏色:如果seleced設(shè)為true,則線條顏色不顯示氯迂。可以將線條寬度設(shè)為大于1時(shí)言缤,則可以自由顯現(xiàn)嚼蚀。
myPath.strokeColor = 'red';
//也可以用new Color來表示.參數(shù)為紅。綠管挟,藍(lán)轿曙。值為0%~100%
myPath.strokeColor = new Color(0.5,0,0.5);
//填充顏色
myPath.fillColor = '#e9e9ff';
//線條寬度
myPath.strokeWidth = 4;
//path前端切口。3種類型:'round', 'square' or 'butt'
myPath.strokeCap = 'round';
//連接處:圓形僻孝,切面导帝,扇形 'miter', 'round' or 'bevel'
myPath.strokeJoin = 'round';
//線條虛線格式:dashArray.參數(shù)1表示小線段長度.第2個(gè)參數(shù)表示間隔長度,為0時(shí)表示為實(shí)線
myPath.dashArray=[40,5];
3.3.8The PathStyle Object
設(shè)置好一個(gè)path的style后可以再賦值給另一個(gè)path。使用mypath.style.
var firstPath = new Path.Circle({
center: [80, 50],
radius: 35
});
firstPath.strokeColor = '#ff0000';
firstPath.fillColor = 'blue';
// secondPath doesn't have a strokeColor yet:
var secondPath = new Path.Circle({
center: [160, 50],
radius: 35
});
// Apply the style of firstPath to that of secondPath:
secondPath.style = firstPath.style;
也可以將style一次性設(shè)置好穿铆,再創(chuàng)給path
var myStyle = {
strokeColor: '#00ffff',
fillColor: '#000000',
strokeWidth: 50
};
var myCircle = new Path.Circle({
center: [100, 100],
radius: 50
});
myCircle.style = myStyle;
3.3.9 Removing Styles
給path中某種style傳值null即可刪除相應(yīng)style您单。或一次性刪除所有style
path.fillColor = 'red';
// Set the fillColor to null to remove it:
path.fillColor = null;
path.style = null;
3.3.10 Working with the Current Style of the Project
所有新創(chuàng)建的item都會自動接收一個(gè)當(dāng)前活躍path style 屬性來作為插畫接口荞雏。我們可以使用currentStyle來改變這些虐秦。
currentStyle 是project和包含當(dāng)前活躍的類似fillColor和strokeColor這些樣式屬性的PathStyle對象。
// Change the current style of the project:
project.currentStyle = {
strokeColor: '#000000',
fillColor: '#ff0000',
strokeWidth: 3
};
// This path will inherit the styles we just set:
var firstPath = new Path.Circle({
center: [100, 100],
radius: 50
});
// Change the current stroke width and fill color of the project:
project.currentStyle.strokeWidth = 8;
project.currentStyle.fillColor = 'green';
//firstPath的樣式不會被改變
// This path will have a green fill and have a strokeWidth of 8pt:
var secondPath = new Path.Circle({
center: [250, 100],
radius: 50
});
3.4 Smoothing, Simplifying & Flattening平滑凤优、簡化和展平
Paper.js有2種不同的用來平滑path的方式:
- path.smooth();改變segment的handlers羡疗,不改變它的point。
- paht.simplify();分析segment數(shù)組别洪,用更優(yōu)的一組segement來代替原segment。減少內(nèi)存使用柳刮,加快繪圖速度挖垛。
3.4.1 Smoothing Paths
3.4.2 Simplifying Paths
path.simplify()通過簡化的方式來平滑path痒钝。path.segments數(shù)組由一列更優(yōu)化的segments代替。減少內(nèi)存使用痢毒,加快繪圖速度送矩。
path.simplify() 方法有一個(gè)可選的tolerance parameter(公差參數(shù)?)
默認(rèn)為2.5.數(shù)字越小就會產(chǎn)生一個(gè)越準(zhǔn)確的曲線哪替,但是點(diǎn)更多栋荸。數(shù)字越大,節(jié)點(diǎn)越少凭舶,但與之前的形狀差異越大晌块。
3.4.3 Flattening Paths
path.flatten(error)將路徑中的曲線轉(zhuǎn)換為具有最大制定錯(cuò)誤的直線。由此產(chǎn)生的直線保證不會比錯(cuò)誤參數(shù)指定的數(shù)量更多帅霜。 默認(rèn)值為0.25
下面例子中匆背,創(chuàng)建一個(gè)圓形,然后使用path.flatten(20)拉直它.
四身冀、Interaction
4.1 Creating Mouse Tools
創(chuàng)建tools與鼠標(biāo)交互
4.1.1 My First Mouse Tool
// Create a new path once, when the script is executed:
var myPath = new Path();
myPath.strokeColor = 'black';
// This function is called whenever the user
// clicks the mouse in the view:
function onMouseDown(event) {
// Add a segment to the path at the position of the mouse:
myPath.add(event.point);
}
4.1.2 Mouse Handler Functions
4.1.3 The Event Object
mouse handler函數(shù)接收一個(gè)event對象钝尸,包含了鼠標(biāo)事件的信息,例如當(dāng)前鼠標(biāo)的位置(event.point)搂根;鼠標(biāo)單擊最后一次時(shí)鼠標(biāo)在項(xiàng)目坐標(biāo)中的位置event.downPoint珍促;鼠標(biāo)的壓力 event.pressure等。
所有細(xì)節(jié)在Mouse Tool Events中剩愧。
4.1.4 Line Tool Example
畫直線的例子猪叙,直線的開始點(diǎn)是鼠標(biāo)點(diǎn)擊的位置,結(jié)束點(diǎn)是鼠標(biāo)松開的位置隙咸。
// We start by defining an empty variable that is visible by both
// mouse handlers.
var myPath;
function onMouseDown(event) {
// The mouse was clicked, so let's put a newly created Path into
// myPath, give it the color black and add the location as the
// path's first segment.
myPath = new Path();
myPath.strokeColor = 'black';
myPath.add(event.point);
}
function onMouseUp(event) {
// The mouse was released, so we add the new location as the end
// segment of the line.
myPath.add(event.point);
}
注意:
這與上一個(gè)例子的區(qū)別是每次鼠標(biāo)點(diǎn)擊的時(shí)候都會創(chuàng)建一個(gè)新path.當(dāng)鼠標(biāo)放開的時(shí)候path完成沐悦。
劃線工具可以有更簡單的寫法,只使用onMouseUp(event) handler. 使用event.downPoint屬性五督。
downPoint:最后一次點(diǎn)擊的點(diǎn)
point:是指相應(yīng)鼠標(biāo)事件觸發(fā)時(shí)的點(diǎn)onMouseDown事件中是鼠標(biāo)按下的點(diǎn)藏否,onMouseUp事件中point是鼠標(biāo)松開時(shí)的點(diǎn)。
function onMouseUp(event) {
var myPath = new Path();
myPath.strokeColor = 'black';
myPath.add(event.downPoint);
myPath.add(event.point);
}
當(dāng)鼠標(biāo)被釋放時(shí)充包,onMouseUp(event) handler被調(diào)用副签。再onMouseUp handlers 我們創(chuàng)建一個(gè)new path, 給一個(gè)黑色的。
var myPath = new Path();
myPath.strokeColor = 'black';
然后使用path.add(segment)添加2個(gè)segments.
1.event.downPoint :目標(biāo)按下的位置的點(diǎn)
2.event.point:onMouseUp中鼠標(biāo)松開的點(diǎn)
4.1.5 Click, Drag and Release Example
4.1.6 Using the Distance that the Mouse has Moved
event.delta:當(dāng)前位置與最后fired位置的差值基矮。在onMouseUp中event.delta描述鼠標(biāo)點(diǎn)擊位置和鼠標(biāo)釋放時(shí)的位置差值淆储。
middlePoint:上一次fired的點(diǎn)和當(dāng)前位置的中點(diǎn)。
lastPoint:上一次fired的點(diǎn)家浇。
downPoint:鼠標(biāo)點(diǎn)擊的點(diǎn)的位置本砰。
point:fired的點(diǎn)
function onMouseUp(event) {
var circle = new Path.Circle({
center: event.middlePoint,
radius: event.delta.length / 2
});
circle.strokeColor = 'black';
circle.fillColor = 'white';
}
onMouseUp中:
- point:鼠標(biāo)松開的點(diǎn)
- middlePoint:按下的點(diǎn)和松開的點(diǎn)的中點(diǎn)
- lastPoint:鼠標(biāo)按下時(shí)的點(diǎn)
- delta: 按下的點(diǎn)和松開的點(diǎn)的差值。實(shí)際是一個(gè)向量由起始點(diǎn)指向終點(diǎn)钢悲。鼠標(biāo)移動的向量点额。
onMouseDown中:
- point:鼠標(biāo)按下的點(diǎn)
- middlePoint:上一次按下的點(diǎn)和這一次按下的點(diǎn)的中點(diǎn)
- lastPoint:鼠標(biāo)按下時(shí)的點(diǎn)
- delta: 上一次按下的點(diǎn)和這一次按下的點(diǎn)的中點(diǎn)
4.1.7~9 Minimum Distance &Maximum Distance
Minimum Distance:設(shè)置onMouseDrag被fired的最小距離.
Maximum Distance:最大距離
fixedDistance:固定距離
五舔株、Project&Item
5.1 Working with item
Item -任何再Paper.js project中顯示的東西:;layers,paths, compound-paths,groups, text items,raster
每一種item都有不同的行為还棱,path包含point载慈,layer能被激活,groups和compound 路徑有children珍手。
5.1.1 Creating New Items
再創(chuàng)建item時(shí)办铡,會自動將其添加在project.activeLayer的item.children列表尾部。
var path = new Path.Circle(new Point(80, 50), 35);
project.activeLayer.lastChild.fillColor = 'red';
5.1.2 Hiding Item
將item.visible 設(shè)為false琳要,則item隱藏寡具。
var circlePath = new Path.Circle(new Point(50, 50), 25);
circlePath.fillColor = 'black';
circlePath.visible = false;
5.1.3 Duplicating Item
復(fù)制item. item.clone().
5.1.4 Selecting Item
再代碼中選擇items或path segment points 和handlers,paper.js會再project的上面畫出可視的輪廓焙蹭。這對于debug非常有用晒杈。
var center = new Point(160, 80);
var circle = new Path.Circle(center, 50);
// Select the second segment point of the path
circle.segments[1].selected = true;
// Select the third segment point of the path
circle.segments[2].selected = true;
// Create a circle path 140pt to the right:
var circle2 = new Path.Circle(center + [140, 0], 50);
circle2.fillColor = 'red';
// Select it:
circle2.selected = true;
5.1.5 Blend Mode & Opacity 混合模式與不透明度
使item變透明。設(shè)置item.opacity的值在0~1之間孔厉。
var circle = new Path.Circle(new Point(80, 50), 35);
circle.fillColor = 'red';
var circle2 = new Path.Circle(new Point(120, 50), 35);
circle2.style = {
fillColor: 'blue',
strokeColor: 'green',
strokeWidth: 10
};
// Make circle2 50% transparent:
circle2.opacity = 0.5;
設(shè)置item.blendMode的屬性來改變item的混合模式拯钻。詳情見item.blendMode。
5.2 Transforming Items
本章介紹如何移動撰豺、縮放和旋轉(zhuǎn)project
5.2.1 Changing the Position of an Item改變item的位置
var circlePath = new Path.Circle(new Point(50, 50), 25);
circlePath.strokeColor = 'black';
// Make a copy of the path and set its stroke color to red:
var copy = circlePath.clone();
copy.strokeColor = 'red';
// Move the copy to {x: 100, y: 100}
copy.position = new Point(100, 100);
上段代碼:
- 創(chuàng)建一個(gè)圓粪般,圓心(50,50),半徑25pt.
- 改變圓心位置污桦。
var circlePath = new Path.Circle(new Point(50, 50), 25);
circlePath.fillColor = 'black'
circlePath.position += new Point(10, 20);
這一段代碼中不改變圓心位置而是使它向右一定10pt,向下移動20pt.
為使item隨鼠標(biāo)移動亩歹,可以將item的位置設(shè)為鼠標(biāo)的位置。下段代碼中item隨鼠標(biāo)移動位置:
var circlePath = new Path.Circle(new Point(50, 50), 25);
circlePath.fillColor = 'black'
function onMouseMove(event) {
circlePath.position = event.point;
}
5.2.2 The Bounding Rectangle of an Item item的矩形邊界凡橱。
item的邊界是一個(gè)矩形小作。使用item.bounds可以顯示item的邊界。
想要知道邊界的寬和高:
var circlePath = new Path.Circle(new Point(50, 50), 25);
console.log(circlePath.bounds.width); // 50
console.log(circlePath.bounds.height); // 50
還可以知道邊界矩形4個(gè)的位置(左上角為0稼钩,0點(diǎn)):
var circlePath = new Path.Circle(new Point(50, 50), 25);
console.log(circlePath.bounds.topLeft); // { x: 25.0, y: 25.0 }
console.log(circlePath.bounds.topRight); // { x: 75.0, y: 25.0 }
console.log(circlePath.bounds.bottomRight); // { x: 75.0, y: 75.0 }
console.log(circlePath.bounds.bottomLeft); // { x: 25.0, y: 75.0 }
5.2.3 Scaling Items 縮放
默認(rèn)的 item.scale(scale)函數(shù)是以item中心點(diǎn)為中心顾稀,縮放相應(yīng)倍數(shù)。如果想設(shè)置縮放中心點(diǎn)可以使用:item.scale(scale, point).
下面的代碼是在(0,0)縮放50%坝撑;
var circlePath = new Path.Circle(new Point(50, 50), 25);
circlePath.style = {
fillColor: 'white',
strokeColor: 'black'
};
// Make a copy of the path and set its stroke color to red:
var copy = circlePath.clone();
copy.strokeColor = 'red';
// Scale the copy by 50% around {x: 0, y: 0}:
copy.scale(0.5, new Point(0, 0));
因?yàn)閕tem.bounds的邊界矩形的角也是點(diǎn)静秆。所以我們可以將該邊界角傳入作為縮放中心點(diǎn).
copy.scale(0.5, circlePath.bounds.topRight);
縮放方式可以在水平與豎直方向上
分別傳入縮放倍數(shù):item.scale(sx, sy).
copy.scale(5, 1.5);
5.2.4 Rotating Items 旋轉(zhuǎn)
item.rotate(angle)傳入旋轉(zhuǎn)度數(shù),沿順時(shí)針方向巡李。
矩形順時(shí)針旋轉(zhuǎn)45度抚笔。傳入值為負(fù)數(shù),表示逆時(shí)針旋轉(zhuǎn)侨拦。
var path = new Path.Rectangle(new Point(50, 50), new Size(100, 50));
path.style = {
fillColor: 'white',
strokeColor: 'black'
};
// Create a copy of the path and set its stroke color to red:
var copy = path.clone();
copy.strokeColor = 'red';
// Rotate the copy by 45 degrees:
copy.rotate(45);
在onFrame handlers重復(fù)旋轉(zhuǎn)來制作動畫:
function onFrame(event) {
// Each frame, rotate the copy by 1 degree:
copy.rotate(1);
}
5.3 Project Hierarchy 等級
paper.js的Project設(shè)計(jì)原則采用 Adobe Illustrator 和 Adobe Photoshop 同樣的堆疊順序原則.
這些應(yīng)用都有層控制面板殊橙,Paper.js有一個(gè)layers的list:project.layers. 無論何時(shí)view在重繪時(shí), Paper都會運(yùn)行這些layers里的item。通過