动画的实现

最后更新于 2023-06-21

通过前一章基础部分的的认识和了解,相信读者已经掌握了如何基于 p5.js 来绘制一幅作品。

现在我们就来绘制一幅太阳从海天相接的地方出来的场景。

想象一下太阳从海的尽头升起的样子,然后用代码实现出来。在实现的过程中,可能会涉及到 p5.js 中关于颜色的运用、圆形的绘制、矩形的绘制等等。

下面是一段简单的代码,来绘制出上面的这个场景。

在接下来的这一节,让我们看看如何来改进这个作品,让太阳缓缓升起,动起来,让其变成一个会动的艺术作品。

## 动画的认识

会动的画面,简称动画,我们在日常的生活中已经屡见不鲜了,比如从小看到大的动画片。那什么是动画呢,为什么看到的动画会动呢?

动画的基本原理其实是基于视觉暂留效应,即当一系列静态图像以一定的速度连续播放时,我们的大脑会将这些图像连接起来,并产生一种错觉,认为它们是连续运动的。这种错觉使我们能够感知到图像的流动和变化。

动画的基本单位是帧(frame),帧代表一幅静态图像。帧率(frame rate)决定了每秒播放的图像数量。常见的帧率 24、30 或 60,即分别是每秒播放 24、30 或 60 帧。帧率越高,动画看起来就越流畅,帧数越少,就会感觉卡顿不流畅。

看到这里,是不是想到了手翻书动画?没错,手翻书动画也是一种简单的动画形式,它也是基于同样的原理实现的。

## 如何在 p5.js 中创建动画

p5.js 提供了渲染循环的机制,默认实现了动画的播放,所以我们只需要关注每一帧的图像绘制,p5.js 会自动帮我们实现播放的效果。

下面是三个涉及到绘制动画的具体函数:

看一个具体的例子:

在上面几行简单的代码中,基于 p5.js 绘制了一个圆形,可以看到这个圆形是静止不动的,因为在每帧的绘制中,我们都是重复在点 (100, 100) 的位置绘制了一个直径为 100 的圆形。

要让它动起来,就需要在每帧的绘制中,让绘制的图像发生不一样的变化,比如让它的大小、位置、颜色等发生变化。

下面来修改一下这个代码,在每帧绘制的时候,改变小球的位置,让小球在画板上动起来。

画板中的圆形已经动起来了,因为每隔一帧它的位置就会增加 1 像素,如此看起来就像动起来了一样。

## 平滑连贯的动画

现在来看另外一个问题,假如每次让它的运动距离增大一些,会发生什么呢?还是会有像上面这样的运动效果么?

在上面的例子中,小球运动的改变量已经变成了 100,可以看到小球一直处于闪烁状态,虽然看起来也是在动,但是却呈现出了不连贯的、让人感觉不舒服的视觉效果。

所以在实现动画的过程中,需要关注每一帧的变化量,如移动的距离、旋转的角度、颜色分量的变化等等,尽可能地让变化量小且连续,这样才能实现平滑细腻的动画效果。

## 动画实现的总结

  1. 需要在 draw 函数的外面定义一个变量,来表示每一帧的变化量,如上面例子中定义的变量 let positionX = 0
  2. 在每一帧的绘制函数 draw 中,对我们需要变化的数值应用变化量,让其发生小且连续的变化,如 positionX += 1
  3. 使用变化后的数值进行具体的绘制,如 circle(positionX, 100, 100)

基于上面的总结,我们来看看假如需要同时对圆形的填充颜色进行变化,该怎么实现。

在上述的例子中,我们添加了一个新的 gray 变量并在每帧对其赋值

gray = map(frameCount % 500, 0, 500, 0, 255)

在这行代码中,使用了 p5.js 的内置函数 map 和内置变量 frameCount

你也可以尝试修改一下 500 这个数字,然后点击运行,看看会发生什么。

动画的基础知识准备得差不多了,看看我们的太阳升起动画该怎么实现。

## 实现太阳升起的动画

## 更多的练习

  1. 跳动的小球
  2. 别碰盒子