• 日常搜索
  • 百度一下
  • Google
  • 在线工具
  • 搜转载

Paper.js入门:动画和图像

到目前为止,在本系列中,我已经介绍了 Paper.js 中的项目和项目、路径和几何以及用户交互。该库还允许您为项目中的各种项目设置动画。如果您将它与基于用户输入的操作能力相结合,您可以创建一些非常酷的效果。本教程将介绍如何在 Paper.js 中为项目设置动画。

本教程的后面部分还将介绍图像处理以及如何处理单个像素的颜色。该库还使您能够从将在最后介绍的矢量创建栅格。

动画基础

Paper.js 中的所有动画都由事件处理程序处理。处理程序内的代码每秒最多执行 60 次。每次执行后视图会自动重绘。逐渐改变函数内部的一些属性可以产生一些非常好的效果。onFrame

onFrame处理函数还接收一个event对象。该对象具有三个属性,它们为咱们提供与动画相关的信息。 

第一个是event.count,它告诉咱们处理程序被执行的次数。第二个是event.delta,它为咱们提供了自上次执行处理程序以来经过的总时间。第三个是event.time,它为咱们提供了自第一帧事件以来经过的时间。

您可以为处理程序中的许多属性设置动画。在咱们的示例中,我将旋转三个矩形并更改中心矩形的色调。考虑下面的代码:

var rectA = new Path.Rectangle({
  point: [300, 100],
  size: [200, 150],
  strokeColor: 'yellow',
  strokeWidth: 10
});

var rectB = rectA.clone();
rectB.strokeColor = 'orange';
rectB.scale(0.8);
var rectC = rectA.clone();
rectC.strokeColor = 'black';
rectC.scale(1.2);

function onFrame(event) {
  rectA.strokeColor.hue += 10 * event.delta;
  rectA.rotate(2);
  rectB.rotate(2);
  rectC.rotate(2);
}

从上面的代码片段可以明显看出,为咱们的矩形设置动画所需的实际代码非常少。event.delta对于矩形 A,咱们在每次执行处理程序时将色调增加 10 倍onFrame。的值event.delta一般会接近 0.01。如果我没有将其值乘以 10,则需要很长时间才能注意到颜色的变化。 

每次执行代码时,我也会将每个矩形旋转 2 度。如果咱们使用该值event.time 来旋转矩形,一段时间后旋转会变得非常快。

See the Pen  Paper.js Animation by Monty (@Shokeen)  on CodePen.

除了一次为整个路径或项目设置动画外,您还可以为各个段设置动画。这个过程本身非常简单。您可以使用path.segments返回一个包含所有段的数组,这些段构成一个路径。可以通过提供index值来访问各个段。在继续之前,我希望您看一下下面的代码。

var aSquare = new Path.RegularPolygon(new Point(550, 200), 4, 100);
aSquare.fillColor = 'pink';
aSquare.fullySelected = true;

function onFrame(event) {
  for (var i = 0; i <= 3; i++) {
    var sinValue = Math.sin(event.time * 4 + i);
    
    aSquare.segments[i].point.x = sinValue * 100 + 350;
  }
  aSquare.segments[1].point.y = sinValue * 50 + 100;
}

在这里,咱们首先使用 Path.RegularPolygon(center, sides, radius)构造函数创建一个正方形。该sides参数确定多边形的边数。该radius参数决定了咱们多边形的大小。我还将fullySelected属性设置为,true以便您可以看到各个点。

在onFrame处理程序内部,我使用 for 循环遍历所有段,并将它们的 x 坐标设置为等于根据它们的索引计算的值。event.time 在函数内部使用Math.sin() 不会产生任何与极值相关的问题,因为 Math.sin()函数的值总是介于 -1 和 1 之间。 

下面的演示展示了咱们的动画正方形,顺便说一句,它不再是正方形,这要归功于咱们onFrame处理程序中的代码。我想建议您为咱们的多边形构造函数以及sin函数尝试不同的值,看看它们如何影响演示中的最终动画。

See the Pen  Paper.js Animated Square by Monty (@Shokeen)  on CodePen.

图像基础

Paper.js 中的图像称为光栅。您可以像任何其他项目一样变换和移动它们。要在您的项目中使用图像,您首先必须使用通常的标签将其添加到网页的标记中img,并给它一个id. 这id稍后将传递给new Raster(id)构造函数。

请记住,您正在使用的图像需要已经加载,并且应该托管在与您的项目相同的网站上。使用托管在其他域上的图像将导致安全错误。在本教程中,咱们将处理以下图像:

Paper.js入门:动画和图像  第1张

要访问上图中各个像素的颜色,您可以使用该 raster.getPixel(x, y)函数,其中 x 和 y 是咱们像素的坐标。下面的代码生成 7*7 像素正方形,填充了位于其左上角的像素颜色:

var raster = new Raster('landscape');
var gridSize = 8;
var rectSize = 7;

raster.on('load', function() {  
  raster.size = new Size(80, 40);

  for (var y = 0; y < raster.height; y++) {
    for (var x = 0; x < raster.width; x++) {
      
      var color = raster.getPixel(x, y);
      var path = new Path.Rectangle( new Point(x, y) * gridSize, new Size(rectSize, rectSize));

      path.fillColor = color;
    }
  }

  project.activeLayer.position = view.center;
});

栅格加载后,咱们将其调整为 80*40。像素。在嵌套for循环中,咱们遍历该栅格的各个像素并创建 7*7 正方形。增加栅格的大小会给咱们带来更好的结果,但执行速度会更慢。这是在左上角可见调整大小的栅格的最终结果:

See the Pen  Paper.js Raster Dots by Monty (@Shokeen)  on CodePen.

如果要隐藏调整大小的栅格,可以将raster.visible属性设置为false。您还可以操纵生成的正方形的颜色。例如,要增加所有正方形中的红色分量,可以使用以下行:

path.fillColor = color + new Color(0.4,0,0);

在这种情况下,最终结果将是:

See the Pen  Paper.js Raster Color Manipulation by Monty (@Shokeen)  on CodePen.

栅格化项目

虽然 Paper.js 是一个矢量图形库,但它还允许您从现有项目创建栅格。为此,您必须使用该item.rasterize()方法。光栅化后,原始项目本身不会从项目中删除。您还可以选择以每英寸像素为单位指定光栅的分辨率。下面的代码从一个多边形以不同的分辨率创建两个栅格:

var aDodecagon = new Path.RegularPolygon(new Point(150, 180), 12, 30);
aDodecagon.fillColor = '#CCAAFC';
  
var dodecRasterA = aDodecagon.rasterize();
dodecRasterA.position.x += 250;
  
var dodecRasterB = aDodecagon.rasterize(150);
dodecRasterB.position.x += 500;
  
aDodecagon.scale(3);
dodecRasterA.scale(3);
dodecRasterB.scale(3);

与中间的多边形相比,分辨率更高的最右边的多边形仍然清晰。这是最终结果:

See the Pen  Paper.js Rasterize by Monty (@Shokeen)  on CodePen.

最后的想法

如果您已经学习了本系列中的所有教程,那么您应该有足够的知识来开始使用 Paper.js。虽然学习库的基础知识很容易,但掌握所有概念需要您付出一些努力。每当您需要有关某个主题的更多信息时,都可以浏览官方网站上 的参考资料。


文章目录
  • 动画基础
  • 图像基础
  • 栅格化项目
  • 最后的想法