在我之前的教程中,我介绍了 Paper.js 中的安装过程和项目层次结构。这一次我将教你关于路径、段和它们的操作。这将使您能够使用库创建复杂的形状。之后,我想介绍 Paper.js 所基于的一些基本几何原理。
使用路径
Paper.js 中的路径由一系列由曲线连接的线段表示。段基本上是一个point和它的两个句柄,它们定义了曲线的位置和方向。不定义线段手柄会导致直线而不是曲线。
使用new Path() const ructor 定义新路径后,您可以在函数的帮助下向其中添加段 path.add(segment)。由于此函数支持多个参数,您还可以一次添加多个段。假设您想在现有路径内的特定索引处插入一个新段。path.insert(index, segment)您可以通过使用该功能来做到这一点。同样,要删除特定索引处的段,您可以使用该path.removeSegment(index)函数。这两个函数都使用从零开始的索引。这意味着 usingpath.removeSegment(3)将删除第四段。您可以关闭使用该path.closed属性绘制的所有路径。它将连接路径的第一段和最后一段。
到目前为止,我们所有的路径都是直线。要创建曲线路径而不为每个段指定句柄,您可以使用该path.smooth()功能。此函数计算路径中所有段的手柄的最佳值,使通过它们的曲线平滑。段本身不会改变它们的位置,如果您为任何段指定了句柄值,这些值将被忽略。下面的代码使用我们讨论过的所有函数和属性来创建四个路径,其中两个是弯曲的。
var aPath = new Path(); aPath.add(new Point(30, 60)); aPath.add(new Point(100, 200)); aPath.add(new Point(300, 280), new Point(280, 40)); aPath.insert(3, new Point(180, 110)); aPath.fullySelected = 'true'; aPath.closed = true; var bPath = aPath.clone(); bPath.smooth(); bPath.position.x += 400; var cPath = aPath.clone(); cPath.position.y += 350; cPath.removeSegment(3); var dPath = bPath.clone(); dPath.strokeColor = 'green'; dPath.position.y += 350; dPath.removeSegment(3);
首先,我们创建一个新路径,然后向其中添加段。Usingpath.insert(3, new Point(180, 110)) 插入一个新段来代替第四段,并将第四段移动到第五个位置。我已设置 fullySelected为true向您展示每条曲线的所有点和手柄。对于第二条路径,我使用了path.smooth()使曲线平滑的函数。删除第四段使用cPath.removeSegment(3)给了我们原始形状,没有任何基于索引的插入。aPath.insert(3, new Point(180, 110));您可以通过在此 CodePen 演示中注释掉来验证这 一点。这是到目前为止我们所有操作的最终结果:
See the Pen Paper.js Paths by Monty (@Shokeen) on CodePen.
预定义形状
Paper.js 支持一些开箱即用的基本形状。例如,要创建一个圆,您可以简单地使用new Path.Circle(center, radius)构造函数。同样,您可以使用 new Path.Rectangle(rect) 构造函数创建一个矩形。您可以指定左上角和右下角,也可以指定矩形的左上角和大小。要绘制圆角矩形,可以使用大小参数决定圆角大小的构造new Path.RoundedRectangle(rect, size)函数。
如果要创建 n 边正多边形,可以使用new Path.RegularPolygon(center, numSides, radius)构造函数来实现。参数center决定了多边形的中心,radius 决定了多边形的半径。
下面的代码将生成我们刚才讨论的所有形状。
var aCircle = new Path.Circle(new Point(75, 75), 60); aCircle.strokeColor = 'black'; var aRectangle = new Path.Rectangle(new Point(200, 15), new Point(400, 135)); aRectangle.strokeColor = 'orange'; var bRectangle = new Path.Rectangle(new Point(80, 215), new Size(400, 135)); bRectangle.strokeColor = 'blue'; var myRectangle = new Rectangle(new Point(450, 30), new Point(720, 170)); var cornerSize = new Size(10, 60); var cRectangle = new Path.RoundRectangle(myRectangle, cornerSize); cRectangle.fillColor = 'lightgreen'; var aTriangle = new Path.RegularPolygon(new Point(120, 500), 3, 110); aTriangle.fillColor = '#FFDDBB'; aTriangle.selected = true; var aDodecagon = new Path.RegularPolygon(new Point(460, 490), 12, 100); aDodecagon.fillColor = '#CCAAFC'; aDodecagon.selected = true;
我们创建的第一个矩形是基于坐标点的。下一个使用第一个点确定矩形的左上角,然后使用大小值绘制其余点。在第三个矩形中,我们还为矩形指定了一个半径。第一个半径参数决定水平曲率,第二个参数决定垂直曲率。
最后两个形状只是使用RegularPolygon构造函数来创建一个三角形和一个十二边形。下面的嵌入式演示显示了我们代码的结果。
See the Pen Paper.js Predefined Shapes by Monty (@Shokeen) on CodePen.
简化和扁平化路径
有两种方法可以创建一个圆圈。第一个是创建许多没有任何句柄的段并将它们紧密地放在一起。这样一来,即使它们被一条直线连接起来,整体的形状还是会更接近一个圆形。第二种方法是只使用四个具有适当值的段作为它们的句柄。这可以节省大量内存,并且仍然可以为我们提供所需的结果。
大多数情况下,我们可以从路径中删除相当多的部分,而不会显着改变其形状。该库提供了一个简单的path.simplify([tolerance])函数来实现这个结果。容差参数是可选的。它用于指定路径简化算法可以偏离其原始路径的最大距离。默认设置为 2.5。如果将参数设置为更高的值,最终曲线会更平滑一些,分段点更少,但偏差可能很大。同样,较低的值将导致非常小的偏差,但包含更多的段。
path.flatten(maxDistance)您还可以使用该功能将路径中的曲线转换为直线。在展平路径时,库尝试使段之间的距离尽可能接近maxDistance。
var aPolygon = new Path.RegularPolygon(new Point(140, 140), 800, 120); aPolygon.fillColor = '#CCAAFC'; aPolygon.selected = true; var bPolygon = aPolygon.clone(); bPolygon.fillColor = '#CCFCAA'; bPolygon.simplify(); var cPolygon = aPolygon.clone(); cPolygon.fillColor = '#FCAACC'; cPolygon.simplify(4); var dPolygon = bPolygon.clone(); dPolygon.fillColor = '#FCCCAA'; dPolygon.flatten(80);
RegularPolygon在上面的代码中,我首先使用上面讨论的函数创建了一个多边形。我有意将selected属性设置为,true以便这些路径中的所有段都可见。然后我从第一个多边形中克隆了第二个多边形并simplify在上面使用了函数。这将段数减少到只有五个。
在第三个多边形中,我将公差参数设置为更高的值。这进一步减少了段的数量。您可以看到所有路径仍然具有相同的基本形状。在最后一条路径中,我使用了该flatten(maxDistance)函数来拉平我们的曲线。该算法试图保持形状尽可能接近原始形状,同时仍然尊重maxDistance约束。这是最终结果:
See the Pen Paper.js Simplify and Flatten by Monty (@Shokeen) on CodePen.
几何和数学
Paper.js 有一些基本的数据类型,如Point、Size和 ,Rectangle用于描述图形项目的几何属性。它们是几何值的抽象表示,例如位置或尺寸。一个点只是描述了一个二维位置,大小描述了二维空间中的抽象维度。这里的矩形表示由左上角点、宽度和高度包围的区域。它与我们之前讨论的矩形角路径不同。与路径不同,它不是一个项目。您可以在此Paper.js 教程中阅读有关它们的更多信息 。
您可以对点和大小执行基本的数学运算——加法、减法、乘法和除法。以下所有操作均有效:
var pointA = new Point(20, 10); var pointB = pointA * 3; // { x: 60, y: 30 } var pointC = pointB - pointA; // { x: 40, y: 20 } var pointD = pointC + 30; // { x: 70, y: 50 } var pointE = pointD / 5; // { x: 14, y: 10 } var pointF = pointE * new Point(3, 2); // { x: 42, y: 20 } // You can check the output in console for verification console.log(pointF);
除了这些基本操作之外,您还可以执行一些舍入操作或生成点和大小的随机值。考虑以下示例:
var point = new Point(3.2, 4.7); var rounded = point.round(); // { x: 3, y: 5 } var ceiled = point.ceil(); // { x: 4, y: 5 } var floored = point.floor(); // { x: 3, y: 4 } // Generate a random point with x between 0 and 50 // and y between 0 and 40 var pointR = new Point(50, 40) * Point.random(); // Generate a random size with width between 0 and 50 // and height between 0 and 40 var sizeR = new Size(50, 40) * Size.random();
该random()函数生成介于 0 和 1 之间的随机值。您可以将它们与适当值的Point或Size对象相乘以获得所需的结果。
到此为止,您需要熟悉使用 Paper.js 创建有用的东西所需的基本数学知识。
最后的想法
完成本教程后,您应该能够创建各种路径和形状、展平曲线或简化复杂路径。现在,您还对可以使用 Paper.js 执行的各种数学运算有了基本的了解。通过结合您在本教程和本系列上一个教程中学到的所有内容,您应该能够在不同的图层上创建复杂的多边形并将它们混合在一起。您还应该能够从路径中插入和删除段以获得所需的形状。