HTML Canvas - 基本动画



canvas 元素完全使用 JavaScript 来绘制形状并向其添加样式。相同的 JavaScript 可用于在 Canvas 元素上制作非常吸引人的动画。由于动画是动态的,因此 Canvas 元素内的对象需要一些时间才能渲染。

控制动画

Canvas 元素形状通常使用方法或自定义函数构建。因此,除非它们在 canvas 元素上正确渲染,否则我们无法向其添加动画。由于动画会改变画布的性质,因此计划更新必须是一个强制性操作。有一些动画方法用于控制 Canvas 元素上动画的功能。下面描述了每种方法

序号 方法和描述
1

setInterval(callback_function, time)

此方法用于在每个时间段内重复给定的任务。它接受一个包含所需任务的函数和以毫秒为单位的时间作为其参数。

2

setTimeout(callback_function, time)

当需要在一定时间内执行一次任务时,使用此方法。它接受可执行函数和以毫秒为单位的时间作为其参数。

3

requestAnimationFrame(callback_function)

此方法更新浏览器以在下一个动画或更新之前执行动画请求。

这些动画方法通常用于 Canvas 元素中开发 2D 游戏和交互式 UI 设计。

添加基本动画的步骤

要向 Canvas 元素添加动画,需要遵循以下步骤

步骤 1 - 清除整个 Canvas 元素 - 要向 Canvas 元素添加任何动画,内部不能有任何不填充整个画布空间的图形。这可以通过调用 clearRect() 方法来实现。

步骤 2 - 保存默认 Canvas 状态 - 由于我们应用各种样式并添加不同的设置,例如变换、切片等,我们必须保存主画布状态以确保我们可以在需要时回滚到主状态。使用 save() 函数来实现此目的。

步骤 3 - 绘制带有附加动画的形状 - 我们使用可用的不同动画渲染绘制的形状。这是将动画应用于 Canvas 元素的第一步。

步骤 4 - 在需要时恢复 Canvas 元素 - 由于我们已经使用 save() 方法保存了画布状态,因此我们可以使用 restore() 函数在绘制新帧之前恢复它们。

示例 1

以下程序演示了clearRect()方法的工作原理以及如何使用它来执行动画。

<!DOCTYPE html>
<html lang="en">
   <head>
      <title>Animations</title>
      <style>
         #button {
            position: absolute;
            top: 350px;
            left: 150px;
         }
      </style>
   </head>
   <body onload="animation();">
      <canvas id="canvas" width="600" height="400" style="border: 1px solid black;"></canvas>
      <script>
         function animation() {
            var canvas = document.getElementById("canvas");
            var context = canvas.getContext("2d");
            context.fillStyle = 'purple';
            context.fillRect(75, 75, 300, 150);
            context.font = '25px Verdana';
            context.fillText('To remove text and rect, press the button', 10, 300);
            document.getElementById('clear').addEventListener('click', function() {
               context.clearRect(0, 0, canvas.width, canvas.height);
            }, false);
         }
      </script>
      <div id="button">
         <input type="button" id="clear" value="Clear the whole Canvas element">
      </div>
   </body>
</html>

输出

上面程序返回的输出如下所示

Steps to Add Basic Animations

如果按下按钮,画布将更改为下面显示的图像

Canvas Changes to The Image

要再次查看文本和形状,请刷新页面。

示例 2

以下代码显示了如何对 Canvas 元素执行简单的动画。

<!DOCTYPE html>
<html lang="en">
   <head>
      <title>Animations</title>
      <style>
         body {
            margin: 10px;
            padding: 10px;
         }
      </style>
   </head>
   <body onload="animate();">
      <canvas id="canvas" width="600" height="200" style="border: 1px solid black;"></canvas>
      <script>
         function animate() {
            window.requestAnimFrame = (function(callback) {
               return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(callback) {
                  window.setTimeout(callback, 1000);
               };
            })();

            function drawShapes(square, context) {
               context.beginPath();
               context.rect(square.x, square.y, square.width, square.height);
               context.fillStyle = 'green';
               context.fill();
               context.lineWidth = square.borderWidth;
               context.strokeStyle = 'black';
               context.stroke();
               context.closePath();
               context.font = '50px Verdana';
               context.fillStyle = 'white';
               context.fillText('Hi', square.x + 15, square.height + 40);
            }

            function animation(square, canvas, context, startTime) {
               // updating the time and speed of movement parameters
               var time = (new Date()).getTime() - startTime;
               var speed = 100;
               var X = speed * time / 1000;
               if (X < canvas.width - square.width - square.borderWidth / 2) {
                  square.x = X;
               }
               // clearing the Canvas element space
               context.clearRect(0, 0, canvas.width, canvas.height);
               drawShapes(square, context);
               // requesting new frame for animation
               requestAnimFrame(function() {
                  animation(square, canvas, context, startTime);
               });
            }
            var canvas = document.getElementById('canvas');
            var context = canvas.getContext('2d');
            var square = {
               x: 0,
               y: 75,
               width: 100,
               height: 100,
               borderWidth: 3
            };
            drawShapes(square, context);
            // buffer time before starting animation
            setTimeout(function() {
               var startTime = (new Date()).getTime();
               animation(square, canvas, context, startTime);
            }, 1000);
         }
      </script>
   </body>
</html>

输出

上面代码返回的动画输出为

Steps to Add Basic Animations Example

动画结束后,正方形的位置将更改如下所示

Position of The Square

示例 3

以下代码演示了在 Canvas 元素帧中对 TutorialsPoint 徽标进行简单的循环。

<!DOCTYPE html>
<html lang="en">
   <head>
      <title>Animations</title>
      <style>
         body {
            margin: 10px;
            padding: 10px;
         }
      </style>
   </head>
   <body onload="animate()">
      <canvas id="context" width="350" height="120" style="border: 1px solid black;background-color: brown;"></canvas>
      <script>
         function animate() {
            var image = new Image();
            image.src = 'https://tutorialspoint.com/themes/home/tp-diamond-logo-white.png';
            var X = 600;
            var Y = 150;
            var velocity = 30;
            var scale = 1.05;
            var y = -4.5;
            var disx = 0.75;
            var imgwidth;
            var imgheight;
            var x = 0;
            var RemoveX;
            var RemoveY;
            var context;
            image.onload = function() {
               imgwidth = image.width * scale;
               imgheight = image.height * scale;
               if (imgwidth > X) {
                  x = X - imgwidth;
               }
               if (imgwidth > X) {
                  RemoveX = imgwidth;
               } else {
                  RemoveX = X;
               }
               if (imgheight > Y) {
                  RemoveY = imgheight;
               } else {
                  RemoveY = Y;
               }
               var canvas = document.getElementById('context')
               context = canvas.getContext('2d');
               return setInterval(draw, velocity);
            }

            function draw() {
               context.clearRect(0, 0, RemoveX, RemoveY);
               if (imgwidth <= X) {
                  if (x > X) {
                     x = -imgwidth + x;
                  }
                  if (x > 0) {
                     context.drawImage(image, -imgwidth + x, y, imgwidth, imgheight);
                  }
                  if (x - imgwidth > 0) {
                     context.drawImage(image, -imgwidth * 2 + x, y, imgwidth, imgheight);
                  }
               } else {
                  if (x > (X)) {
                     x = X - imgwidth;
                  }
                  if (x > (X - imgwidth)) {
                     context.drawImage(image, x - imgwidth + 1, y, imgwidth, imgheight);
                  }
               }
               context.drawImage(image, x, y, imgwidth, imgheight);
               x += disx;
            }
         }
      </script>
   </body>
</html>

输出

代码返回的循环输出如下所示

Simple Looping Loop Output
广告