作者: Nightingale1204 | 来源:发表于2017-12-29 17:21 被阅读0次

原Tutorials链接

paper.js的学习记录,参考原英文教程

一.开始使用

1.1 paper.js的使用方式

2种,PaperScript 或者 JavaScript

1.2 直接使用JavaScript

1.2.1 Paper.js Architecture

scope,projects, views, item,

,path(相当于画笔,可以画point,矩形,圆形,线段等等), size.

1.2.2 Setting Up a Scope

步骤:

1.关联canvas元素

2.创建project和view:  paper.setup("canvas id");

3.设置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创建一个空的project同时为这个canvas创建一个view两种方式
        //1. paper.setup(canvas);
        //2. 使用id
        paper.setup("myCanvas");
        //创建一个Paper.js的path来在该canvas上画一条直线
        var path = new paper.Path();
        //给这个直线设置颜色属性
        path.strokeColor = 'black';
        //设置直线的起始点
        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个鼠标handler和1个动画handler和1个view resize时的handler

  1. onFrame(http://paperjs.org/reference/view/#onframe)
    使用onFrame时,自动实现view.draw()方法。
  2. onResize (http://paperjs.org/reference/view/#onresize)

原网站上的例子问题:
不知道为什么canvas的长宽一直被设置为304 X 154. 使用F12不断打开和关闭窗口,canvas大小会不断变大,刷新后又回到最初状态

canvas默认大小304 X 154.补充canvas知识:https://www.cnblogs.com/JamKong/p/4987163.html

1.2.5 Working with Tools

问题 :Tools和Handlers的区别?
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调用。

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创建一个空的project同时为这个canvas创建一个view两种方式
        //1. paper.setup(canvas);
        //2. 使用id
        paper.setup("myCanvas");
        //path 的声明放在外面,点击是=时回与之前的点链接起来。放在mousedown函数里就不会有首尾链接。但点击鼠标不会有画点
        // var path = new Path();
        var path;
        function mousedown(event){
          path = new Path();
          path.strokeColor = 'red';
          //相当于定义一个起点画笔动作。如果注释掉这一行画云操作会出错。
         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都是用来描述图像几何属性的对象。他们抽象的代表了一些几何特征,例如位置和尺寸。但是他们并不直接表示一个带有project的图像{?a graphical item within a project}。

注意:
在paper.js中图像出现在层列表中(layer list),在project中可见。类比于现实世界中的物理物质。为了描述它们的位置和大小,Paper.js 有不同的基础类型。这些基础类型仅仅是包含了描述图像几何特征的数值。

这意味着当我们在代码中新建了一个Point时,实际上只是在view中创建了一个位置的描述,但是并没有创建一个包含这个point的path来作为一个segment。

var myPoint = new Point(10, 20); 
console.log(myPoint); // { x: 10, y: 20 }

为创建一个把包含point作为segment的path,需要明确地使用new Path()构造器来创建一个path同时添加point作为这个path的第一个segment。
更多paths和segments的细节
http://paperjs.org/tutorials/paths/working-with-path-items/

var myPath = new Path();
myPath.add(myPoint);

运行这一段脚本会在Paper.js的project中产生一个“物理”path,这个path子在myPoint的位置有一个segment。

注意:
这里myPath的segment和点myPoint不是一样的,myPoint只是简单描述用来产生myPath第一个segment的坐标。在segment创建之后改变myPoint segment不会再改变(?)。

2.1.1 Point

Point对象描述一个二维坐标。它有2个属性x,y。代表位置的x轴和y轴。
可以直接提供x、y的值来创建Point对象,也可以不指定xy值,默认为0. x,y可以分别赋值和改变。
point的两种复制方式,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时1也会改变。
var firstPoint = new Point(20, 40);
var secondPoint = firstPoint;
除了直角坐标也可以用极坐标表示。angel和length

2.1.2 Size

Size对象在二维空间描述抽象的尺寸。2个属性width和height。
和Point对象类似,Size的创建方式也有2种:1.直接给width和height赋值,或者不赋值,,默认为0。 width和height可以分开赋值和获取。width和height的赋值可以是point的值、数组、对象。加减乘除操作。

2.1.3 Rectangle

[Rectangle(http://paperjs.org/reference/rectangle)
对象可以看做Point和Size对象的联合,描述了2维的位置和尺寸。因此它包含4个属性:x,y,width,height. x和y描述矩形左上角的点,width和height是尺寸。此外,还有point和size属性,使用Point和Size来获得。

Rectangle对象可以有多种方式来创建,一种是传入一个Point和Size对象给new Rectangle(point, size),或Rectangle(x,y,width,height)或是Rectangle(point1,point2)

2.2 Object Conversion

可以自由转换参数,所有的基础类型可以自由的描述为数组或这js对象。

2.3 Mathematical Operations

Paper.js允许基本数据类型之间使用代数操作,Point和Size可以使用数字或这其它point和Size进行加减乘除操作。

// 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 }

对象转换:

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

创建一个随机值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的头等公民。在学习编写脚本时,了解它的基本原理是一个很大的优势。毕竟,矢量图形中的单词矢量是有原因的。

下面是一个向量几何的优美的例子,下面是一个画笔的例子,只有24行的代码,它提供了一个像画笔动作一样的鼠标操作,根据速度画笔可变厚度,拥有自然的表达感。

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 只一步步解释,但是 再看这个例子之前,先理解向量几何是非常重要的。

<a name="points-and-vectors" title="Points and Vectors" class="anchor"></a>

2.4.1 Point and Vector

在很多方面,vector和point很相似。都在直角坐标系中,但point描述位置,vector表示相关信息:从一个点到另一个的路径。下面将逐步解释vectors和points。

首先使用Point对象创建2个点,描述文档中的绝对位置。

var point1 = new Point(50,50);
var point2 = new Point(110,200);
image.png

从点1到点2,相当于在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个分开的值更容易,使用point 直接相减得到向量值:

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

注意:

Mathematical Operations tutorial.中有更多算术操作
需要注意的是代码中相减的结果(向量)仍然是一个point对象,严格来说,point和vector没有区别,只是point表示绝对位置, vector表示相对位置。


向量也可以被描述成箭头(array)。与箭头相似,向量指向特定的方向,同时指明在这个方向上移动的长度。因此常使用angle和length来描述向量。
Point的对象有2个属性:point.angel和point.length。可以分别修改。

console.log(vector.length);
// 161.55494
console.log(vector.angle);
// 68.19859
image.png

默认角度使用度数来表示

向量的简单使用是把它添加到一个绝对位置点上。结果仍然是一个绝对点。我们可以把一个向量值加到不同的点上。下图中我们看到的向量都是相同的恩但是因为起始点不同结果都不同。


image.png

2.4.2 Calculating with Vectors

2.4.3 Vector Addition and Subtraction

向量可以相加,结果等同于从1个位置到另一个位置的2步操作,结果是第三个向量。
首先有4个点:

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个向量:

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, 重新得到一个tempPoint。然后再加上vector2得到目标点endPoint.

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

但是这样分开加有点复杂.我们可以直接取,2个向量相加的结果。

var vector = vector1 + vector2;
image.png

向量相加是头+尾。向量相减表示头+相反方向的尾。

var vector = vector1 - vector2;
image.png

注意:
向量相加减的操作等同于向量xy坐标加减,但是角度和长度加减无效。

2.4.3 向量的乘除

向量的乘除不改变方向,只改变长度。

var bigVector = smallVector * 3;

注意:js限制,需要将向量值放在操作符左边。因为左边定义了返回类型。因次这样写会出错。

var bigVector = 3 * smallVector;//错误写法

2.4.4 改变向量长度

除了乘除改变向量的长度,还可以直接改变vector的length属性。
首先使用Point构造器创建一个vector. vector和point是一种类型。

var vector = new Point(24, 60);
console.log(vector.length);
// 64.62198 .长度计算方法60的平法+24的平方,开根号

下面改变向量的length属性。这与之前乘法的例子l类似,但这里是直接操作对象:

vector.length = vector.length * 3;
console.log(vector.length);
// 193.86593

也可以直接设置length的值

 vector.length = 100;

使用point.normalize()也可以改变向量的长度。归一化一个向量是指将它的长度设为1.也可以自定义为别的数字。

var vector = new Point(24,60);
var normalizedVector = vector.normalize();
console.log(vector.length);
//64.62198
console.log(normalizedVector.length);
// 1

注意此时normalizedVector的长度值为1,原始vector不变。normalize()返回一个新的归一化向量对象。
如果我们把向量标准化为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

再创建path和shapes时旋转向量非常有用,它允许我们在某个特定角度定义一个相对方向来转向另一个方向。在Working with Mouse Vectors有很好的演示例子。
rotated向量用来构建与鼠标移动并行的paths。

paper.js里的度数:


image.png

-180度和180度在一个位置。度数设置可以大于180度。
有2种方法来改变向量的角度:

  1. 设置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. 数值相加
vector.angle = vector.angle + 90;
//或
vector.angle += 90;

2.4.6 Operations, Methods and Properties

数学运算(+、 - 、*、/)和数学方法rotate()和normalize()并不改变向量和点本身。相反,它们返回一个新的对象。这意味这他们可以在表达式中链接和组合。

var point = event.middlePoint
        + event.delta.rotate(90);

相反,改变向量的angle和length会改变向量本身。因此,我们在直接改变对象的值时需要特别小心,使用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组成。一个segment由一个point和2个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()也支持多个参数。可以添加读个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对象代表二维空间的一个点,它并不是path中的一个锚点。当Point作为参数传入add()或insert()函数时,动态转换为Segment类型。

3.1.3 Smoothing Paths

使用path.smooth()方法来自动平滑path。这个函数计算path的segment的handlers的最优值来创建平滑的曲线。segments不移动当前path的segments的handler设置忽略。

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

默认通过new Path()创建的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));

为封闭这个path,将path.closed属性设为true后Paper.js 会自动连接第一个segment和最后一个segment。

myPath.closed = true;

3.1.5 Removing Segments and Paths

从path中使用path.removeSegment(index)删除segment。index为segment索引地址,从0开始。
首先创建一个圈。

var myCircle = new Path.Circle(new Point(100, 70), 50);
myCircle.strokeColor = 'black';
myCircle.selected = true;

有4个segment。删除第一个segment:

myCircle.removeSegment(0);

整个删除item.remove():

myCircle.remove();

3.2 Creating Predefined Shapes 创建预定义形状

使用new Path()创建一个没有点的空path。使用new Path.Circle(center,radius)和new Path.Rectangle(point,size)创建path时,自动为其添加segments来创建预定义形状。

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 矩形

创建矩形时可以传入点也可以给new Path.Rectangle(rect)传入rectangle。

注意:
一个Rectangle对象是一个矩形的抽象代表

例如:我们在(x:0,y:0)和(x:50,y:50)创建一个矩形。使用new Path.Rectangle(rect)构造器创建一个符合描述的形状路径。

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)报错。应该不带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规则的多边形

使用new Path.RegularPolygon(center, numSides, radius)
center:中心点;
numSides:边数;
radius:半径。

Path 所有的构造器:Path reference

3.3 Using Color and Style

3.3.1 Example Path

下面例子中使用一个对号型路径:

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设为true,则线条颜色不显示。可以将线条宽度设为大于1时,则可以自由显现。
        myPath.strokeColor = 'red';
        //也可以用new Color来表示.参数为红。绿,蓝。值为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.参数1表示小线段长度.第2个参数表示间隔长度,为0时表示为实线
        myPath.dashArray=[40,5];

3.3.8The PathStyle Object

设置好一个path的style后可以再赋值给另一个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一次性设置好,再创给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即可删除相应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

所有新创建的item都会自动接收一个当前活跃path style 属性来作为插画接口。我们可以使用currentStyle来改变这些。

currentStyle 是project和包含当前活跃的类似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数组,用更优的一组segement来代替原segment。减少内存使用,加快绘图速度。

3.4.1 Smoothing Paths

3.4.2 Simplifying Paths

path.simplify()通过简化的方式来平滑path。path.segments数组由一列更优化的segments代替。减少内存使用,加快绘图速度。
path.simplify() 方法有一个可选的tolerance parameter(公差参数?)
默认为2.5.数字越小就会产生一个越准确的曲线,但是点更多。数字越大,节点越少,但与之前的形状差异越大。

3.4.3 Flattening Paths

path.flatten(error)将路径中的曲线转换为具有最大制定错误的直线。由此产生的直线保证不会比错误参数指定的数量更多。 默认值为0.25
下面例子中,创建一个圆形,然后使用path.flatten(20)拉直它.

四、Interaction

4.1 Creating Mouse Tools

创建tools与鼠标交互

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函数接收一个event对象,包含了鼠标事件的信息,例如当前鼠标的位置(event.point);鼠标单击最后一次时鼠标在项目坐标中的位置event.downPoint;鼠标的压力 event.pressure等。
所有细节在Mouse Tool Events中。

4.1.4 Line Tool Example

画直线的例子,直线的开始点是鼠标点击的位置,结束点是鼠标松开的位置。

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

注意:
这与上一个例子的区别是每次鼠标点击的时候都会创建一个新path.当鼠标放开的时候path完成。
划线工具可以有更简单的写法,只使用onMouseUp(event) handler. 使用event.downPoint属性。
downPoint:最后一次点击的点
point:是指相应鼠标事件触发时的点onMouseDown事件中是鼠标按下的点,onMouseUp事件中point是鼠标松开时的点。

function onMouseUp(event) {
    var myPath = new Path();
    myPath.strokeColor = 'black';
    myPath.add(event.downPoint);
    myPath.add(event.point);
}

当鼠标被释放时,onMouseUp(event) handler被调用。再onMouseUp handlers 我们创建一个new path, 给一个黑色的。

    var myPath = new Path();
    myPath.strokeColor = 'black';

然后使用path.add(segment)添加2个segments.
1.event.downPoint :目标按下的位置的点
2.event.point:onMouseUp中鼠标松开的点

4.1.5 Click, Drag and Release Example

4.1.6 Using the Distance that the Mouse has Moved

event.delta:当前位置与最后fired位置的差值。在onMouseUp中event.delta描述鼠标点击位置和鼠标释放时的位置差值。
middlePoint:上一次fired的点和当前位置的中点。
lastPoint:上一次fired的点。
downPoint:鼠标点击的点的位置。
point:fired的点

function onMouseUp(event) {
    var circle = new Path.Circle({
        center: event.middlePoint,
        radius: event.delta.length / 2
    });
    circle.strokeColor = 'black';
    circle.fillColor = 'white';
}

onMouseUp中:

  • point:鼠标松开的点
  • middlePoint:按下的点和松开的点的中点
  • lastPoint:鼠标按下时的点
  • delta: 按下的点和松开的点的差值。实际是一个向量由起始点指向终点。鼠标移动的向量。

onMouseDown中:

  • point:鼠标按下的点
  • middlePoint:上一次按下的点和这一次按下的点的中点
  • lastPoint:鼠标按下时的点
  • delta: 上一次按下的点和这一次按下的点的中点

4.1.7~9 Minimum Distance &Maximum Distance

Minimum Distance:设置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

再创建item时,会自动将其添加在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 设为false,则item隐藏。

var circlePath = new Path.Circle(new Point(50, 50), 25);
circlePath.fillColor = 'black';
circlePath.visible = false;

5.1.3 Duplicating Item

复制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变透明。设置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;

设置item.blendMode的属性来改变item的混合模式。详情见item.blendMode

5.2 Transforming Items

本章介绍如何移动、缩放和旋转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. 创建一个圆,圆心(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随鼠标移动,可以将item的位置设为鼠标的位置。下段代码中item随鼠标移动位置:

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的边界是一个矩形。使用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个的位置(左上角为0,0点):

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 缩放

默认的 item.scale(scale)函数是以item中心点为中心,缩放相应倍数。如果想设置缩放中心点可以使用: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));

因为item.bounds的边界矩形的角也是点。所以我们可以将该边界角传入作为缩放中心点.

copy.scale(0.5, circlePath.bounds.topRight);

缩放方式可以在水平与竖直方向上
分别传入缩放倍数:item.scale(sx, sy).

copy.scale(5, 1.5);

5.2.4 Rotating Items 旋转

item.rotate(angle)传入旋转度数,沿顺时针方向。
矩形顺时针旋转45度。传入值为负数,表示逆时针旋转。

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重复旋转来制作动画:

function onFrame(event) {
    // Each frame, rotate the copy by 1 degree:
    copy.rotate(1);
}

5.3 Project Hierarchy 等级

paper.js的Project设计原则采用 Adobe Illustrator 和 Adobe Photoshop 同样的堆叠顺序原则.
这些应用都有层控制面板,Paper.js有一个layers的list:project.layers. 无论何时view在重绘时, Paper都会运行这些layers里的item。通过

相关文章

  • 学,学,学

  • 学?学!

    学习这个东西永远都只是自己的事情,你想学他不分早晚。有的人学活到老学到老,那么有的人他从小就不爱学,那么后来终归是...

  • 如何学习

    学什么?……盯着『目标』学 怎么学?……带着『问题』学 向谁学?……跟着『高手』学

  • 有没有感觉退休后学习热情高涨?

    有没有觉得退休后学习热情高涨?学唱歌、学跳舞、学画画,又学摄影、学书法、学播音,还学厨艺、学写作、学游泳,学打太极...

  • 《学霸与学渣》

    学霸与学渣 角色:学霸A , 学霸B,学神,学渣A,学渣B,老师 演员要求: 学霸A:能尽快哭出来,历史学霸 学霸...

  • 我最想干的事

    学陶艺 学画画 学美妆 学盘发 学烘焙 每天跑步快走一小时 学瑜伽 每天读一小时读书. 学美食 学佛法 学茶道 学...

  • 《新闻采访与写作》课程简介

    新闻学研究包括理论新闻学、历史新闻学和实用新闻学。 实用新闻学包括新闻采访学、新闻写作学、新闻编辑学和新闻评论学。...

  • 史上最快的学习技能的方法

    听说你想学英语,学吉他,学编程,学画画,学唱歌,学做菜,学瑜伽,学打羽毛球,学游泳,学围棋,却不知道怎么入门? 找...

  • 最近

    浮躁得很,不能再这样,要振作起来,假期搞好CNN,学一学C,学一学python,学一学数学,学一学英语,最好再能撂...

  • 13/70 自我介绍:体验者、持续者和践行者

    首先,我是一个生活的体验者,我喜欢尝试不同的事情。比如,我学开车、学营养学、学烹饪、学瑜伽、学健身、学游泳、学演讲...

网友评论

      本文标题:

      本文链接:https://www.haomeiwen.com/subject/tzqwgxtx.html