Canvas学习笔记 | 4个示例详细讲述缓动动画,绝对的干货

lxf2023-03-16 17:41:01

本文正在参加「 . 」

前言

大家好,我是汪小成。最近在学习Canvas。这篇文章是我学习Canvas缓动动画时记的笔记,欢迎大家审阅。

什么是缓动动画?

缓动动画,指的是带有一定缓冲效果的动画。在动画过程中,物体在某一段时间会“渐进加速”或“渐进减速”,从而让物体运动看起来更为自然而逼真。

缓动动画的分类

缓动动画可以分为两种,即缓入动画缓出动画

缓动动画的实现步骤

在Canvas中,想要实现缓动动画,一般需要如下五个步骤:

  1. 定义一个0 ~ 1之间的缓动系数easing
  2. 计算出物体与目标点之间的距离。
  3. 计算出当前速率,其中当前速率 = 距离 * 缓动系数
  4. 计算新的位置,其中新的位置 = 当前位置 + 当前速度
  5. 重复执行第2~4步,直到物体达到目标。

为了更直观地理解实现缓动动画的五个步骤,笔记使用mermaid绘制了一个简易流程图。

graph TD
start(开始) --> a[1.定义缓动系数]
a --> b[2.计算物体与目标点间的距离]
b --> c[3.计算物体的当前速率]
c --> d[4.计算出物体新的位置]
d --> e{物体是否到达终点}
e--是-->f(结束)
e--否-->b

当前速率的计算方式

通过如下方式计算物体的当前速率:

var targetX = 任意位置;
var targetY = 任意位置;
// 动画循环
var vx = (targetX - object.x) * easing;
var vy = (targetY - object.y) * easing;

targetXtargetY分别为目标点的横坐标和纵坐标,easing为缓动系数,vxvy分别为物体在x轴方向和y轴方向上的速率。

示例

缓动动画的相关理论知识大体如上,为了更好地理解缓动动画,接下来我们着手编写一些简单的示例。

示例一:X轴方向上的缓动动画

示例源码:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>X轴方向上的缓动动画</title>
    <script type="text/javascript" src="ball.js"></script>
  </head>
  <body>
    <canvas id="canvas" width="400" height="200"
      style="border: 1px dashed #333333" ></canvas>
    <script>
      window.onload = function () {
        // 1、获取 Canvas 对象
        var canvas = document.getElementById("canvas");
        // 2、获取上下文环境对象
        var ctx = canvas.getContext("2d");
        // 3、开始绘制图形

        var ball = new Ball(0, canvas.height / 2);
        // (1)定义一个0~1之间的缓动系数easing。
        var easing = 0.05;
        // (2)计算出物体与终点之间的距离。
        var targetX = canvas.width * (3 / 4);

        (function frame() {
          ctx.clearRect(0, 0, canvas.width, canvas.height);
          // (3)计算出当前速度,其中当前速率=距离x缓动系统。
          var vx = (targetX - ball.x) * easing;
          // (4)计算新的位置,其中新的位置=当前位置+当前速度。
          ball.x += vx;
          ball.fill(ctx);
          // (5)重复执行第2~4步,直到物体达到目标。
          window.requestAnimationFrame(frame);
        })();
      };
    </script>
  </body>
</html>

效果图:

Canvas学习笔记 | 4个示例详细讲述缓动动画,绝对的干货

示例程序的效果是一个从左到右缓动的点,笔者在制作Gif图片时设置的一直循环这个动作。

说明:

easing是缓动系数,在每一帧中都将物体与终点之间的距离乘以缓动系数,求出物体的当前速率。随着距离的不断减小,速度也就不断减小。当系数越接近于1,小球移动得越快;当系数越接近于0,小球移动得越慢。

示例二:任意方向上的缓动动画

示例源码:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>任意方向上的缓动动画</title>
    <script type="text/javascript" src="ball.js"></script>
  </head>
  <body>
    <canvas id="canvas" width="300" height="300"
      style="border: 1px dashed #333333" ></canvas>
    <script>
      window.onload = function () {
        // 1、获取 Canvas 对象
        var canvas = document.getElementById("canvas");
        // 2、获取上下文环境对象
        var ctx = canvas.getContext("2d");
        // 3、开始绘制图形

        var ball = new Ball(0, 0);
        // (1)定义一个0~1之间的缓动系数easing。
        var easing = 0.05;
        // (2)计算出物体与终点之间的距离。
        var targetX = canvas.width * (3 / 4);
        var targetY = canvas.height * (3 / 4);

        (function frame() {
          ctx.clearRect(0, 0, canvas.width, canvas.height);
          // (3)计算出当前速度,其中当前速率=距离x缓动系统。
          var vx = (targetX - ball.x) * easing;
          var vy = (targetY - ball.y) * easing;
          // (4)计算新的位置,其中新的位置=当前位置+当前速度。
          ball.x += vx;
          ball.y += vy;
          ball.fill(ctx);
          // (5)重复执行第2~4步,直到物体达到目标。
          window.requestAnimationFrame(frame);
        })();
      };
    </script>
  </body>
</html>

效果图:

Canvas学习笔记 | 4个示例详细讲述缓动动画,绝对的干货

示例程序的效果是一个从左上到右下的缓动的点,笔者在制作Gif图片时设置的一直循环这个动作。

说明:

对于任意方向的缓动动画,我们只需要分解为x轴和y轴两个方向,然后分别进行处理即可。

示例三:追随鼠标的小球

示例源码:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>追随鼠标的小球</title>
    <script type="text/javascript" src="ball.js"></script>
  </head>
  <body>
    <canvas id="canvas" width="300" height="300"
      style="border: 1px dashed #333333" ></canvas>
    <script>
      window.onload = function () {
        // 1、获取 Canvas 对象
        var canvas = document.getElementById("canvas");
        // 2、获取上下文环境对象
        var ctx = canvas.getContext("2d");
        // 3、开始绘制图形
		
        var target = {x: canvas.width / 2, y: canvas.height / 2};
		
        canvas.addEventListener('mousemove', function(event) {
          target = {
            x: event.clientX,
                y: event.clientY
          }
        });

        var ball = new Ball(canvas.width / 2, canvas.height / 2);
        var easing = 0.05;

        (function frame() {
          ctx.clearRect(0, 0, canvas.width, canvas.height);
          var vx = (target.x - ball.x) * easing;
          var vy = (target.y - ball.y) * easing;
          ball.x += vx;
          ball.y += vy;
          ball.fill(ctx);
          // (5)重复执行第2~4步,直到物体达到目标。
          window.requestAnimationFrame(frame);
        })();
      };
    </script>
  </body>
</html>

效果图:

Canvas学习笔记 | 4个示例详细讲述缓动动画,绝对的干货

说明:

给Canvas添加了一个鼠标移动事件监听,获取鼠标的位置,然后将目标点设置成鼠标的位置,追随鼠标效果就实现啦。

示例四:缓动动画应用于半径

Canvas中,缓动动画不仅可以用于物体的运动,还可以应用于物体的其它各种属性,包括大小、颜色、透明度以及旋转等。

不管缓动动画应用于什么方面,实现思路是一样的,都是如下两个步骤:

  1. 当前速率 = (最终值 - 当前值) * 缓动系数
  2. 新值 = 当前值 + 当前速度

示例源码:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>缓动动画应用于半径</title>
    <script type="text/javascript" src="ball.js"></script>
  </head>
  <body>
    <canvas id="canvas" width="300" height="300"
      style="border: 1px dashed #333333" ></canvas>
    <script>
      window.onload = function () {
        // 1、获取 Canvas 对象
        var canvas = document.getElementById("canvas");
        // 2、获取上下文环境对象
        var ctx = canvas.getContext("2d");
        // 3、开始绘制图形
        var ball = new Ball(canvas.width / 2, canvas.height / 2);
        var easing = 0.05;
        var targetRadius = 100;

        (function frame() {
          ctx.clearRect(0, 0, canvas.width, canvas.height);
          
          var vRadius = (targetRadius - ball.radius) * easing;
          ball.radius += vRadius;

          ball.fill(ctx);

          if (vRadius < 0.5 && vRadius > 0) {
            targetRadius = 10;
          }
          if (vRadius < 0 && vRadius > -0.5) {
            targetRadius = 100;
          }

          window.requestAnimationFrame(frame);
        })();
      };
    </script>
  </body>
</html>

效果图:

Canvas学习笔记 | 4个示例详细讲述缓动动画,绝对的干货

说明:

本示例的效果是一个逐渐变大的小球,当小球变到最大后,重新设置目标大小,让小球再逐渐变小。然后一直循环。