學(xué)

原Tutorials鏈接

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全局注入的兩種方式:

  1. paper.install(window);

  2.  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

  1. onFrame(http://paperjs.org/reference/view/#onframe)
    使用onFrame時(shí)亏推,自動實(shí)現(xiàn)view.draw()方法。
  2. 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);
image.png

從點(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;
image.png

使用向量來表示這2個(gè)分開的值更容易漱办,使用point 直接相減得到向量值:

var vector = point2 - point1;
// = { x: 110, y: 200 } - { x: 50, y: 50 }
// = { x: 60, y: 150 }
image.png

注意:

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
image.png

默認(rèn)角度使用度數(shù)來表示

向量的簡單使用是把它添加到一個(gè)絕對位置點(diǎn)上。結(jié)果仍然是一個(gè)絕對點(diǎn)蟹但。我們可以把一個(gè)向量值加到不同的點(diǎn)上躯泰。下圖中我們看到的向量都是相同的恩但是因?yàn)槠鹗键c(diǎn)不同結(jié)果都不同。


image.png

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 }
image.png

從startPoint開始客叉,首先加上vector1诵竭, 重新得到一個(gè)tempPoint。然后再加上vector2得到目標(biāo)點(diǎn)endPoint.

var tempPoint = startPoint + vector1;
var endPoint = tempPoint + vector2;
image.png

但是這樣分開加有點(diǎn)復(fù)雜.我們可以直接取兼搏,2個(gè)向量相加的結(jié)果卵慰。

var vector = vector1 + vector2;
image.png

向量相加是頭+尾。向量相減表示頭+相反方向的尾佛呻。

var vector = vector1 - vector2;
image.png

注意:
向量相加減的操作等同于向量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ù):


image.png

-180度和180度在一個(gè)位置派敷。度數(shù)設(shè)置可以大于180度。
有2種方法來改變向量的角度:

  1. 設(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 }

長度不變撰洗。

  1. 數(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的方式:

  1. path.smooth();改變segment的handlers羡疗,不改變它的point。
  2. 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的位置

item.position

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);

上段代碼:

  1. 創(chuàng)建一個(gè)圓粪般,圓心(50,50),半徑25pt.
  2. 改變圓心位置污桦。
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。通過

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市蛀柴,隨后出現(xiàn)的幾起案子螃概,更是在濱河造成了極大的恐慌,老刑警劉巖鸽疾,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異训貌,居然都是意外死亡制肮,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進(jìn)店門递沪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來豺鼻,“玉大人,你說我怎么就攤上這事款慨∪屐” “怎么了?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵檩奠,是天一觀的道長桩了。 經(jīng)常有香客問我,道長埠戳,這世上最難降的妖魔是什么井誉? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮整胃,結(jié)果婚禮上颗圣,老公的妹妹穿的比我還像新娘。我一直安慰自己屁使,他們只是感情好在岂,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著蛮寂,像睡著了一般蔽午。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上共郭,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天祠丝,我揣著相機(jī)與錄音,去河邊找鬼除嘹。 笑死写半,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的尉咕。 我是一名探鬼主播叠蝇,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼年缎!你這毒婦竟也來了悔捶?” 一聲冷哼從身側(cè)響起铃慷,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蜕该,沒想到半個(gè)月后犁柜,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡堂淡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年馋缅,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片绢淀。...
    茶點(diǎn)故事閱讀 39,696評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡萤悴,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出皆的,到底是詐尸還是另有隱情覆履,我是刑警寧澤,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布费薄,位于F島的核電站硝全,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏义锥。R本人自食惡果不足惜柳沙,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望拌倍。 院中可真熱鬧赂鲤,春花似錦、人聲如沸柱恤。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽梗顺。三九已至泡孩,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間寺谤,已是汗流浹背仑鸥。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留变屁,地道東北人眼俊。 一個(gè)月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像粟关,于是被迫代替她去往敵國和親疮胖。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評論 2 353

推薦閱讀更多精彩內(nèi)容