HTML5 Canvas动画实例

2023-06-28 08:49:04

 在开发在线游戏时,绘制动画是非常重要的。本文介绍一个使用Canvas API实现的动画实例——游戏人物的跑步动画。

01、动画的概念及原理

1、动画

动画是通过一幅幅静止的、内容不同的画面(即帧)快速播放来呈现的,使人们在视觉上产生动的感觉。这是利用了人类眼睛的视觉暂留原理。利用人的这种生理特性可制作出具有高度想象力和表现力的动画影片。

2. 原理

人们在看画面时,画面会在大脑视觉神经中停留大约1/24秒,如果每秒更替24个画面或更多,那么前一个画面还没在人脑中消失之前,下一个画面进入人脑,人们就会觉得画面动起来了,它的基本原理与电影、电视一样,都是视觉原理。

在计算机上要实现动画效果,除了绘图外,还需要解决下面两个问题。

(1) 定期绘图,也就是每隔一段时间就调用绘图函数进行绘图。动画是通过多次绘图实现的,一次绘图只能实现静态图像。

可以使用setInterval()函数设置一个定时器,语法如下:

setInterval(函数名,时间间隔)

时间间隔的单位是毫秒(ms),每经过指定的时间间隔系统都会自动调用指定的函数完成绘画。

(2) 清除先前绘制的所有图形。物体已经移动开来,可原来的位置上还保留先前绘制的图形,这样当然不行。解决这个问题最简单的方法是使用clearRect(x, y, width, height)方法清除画布中指定区域的内容。

图1是一个方向(一般都是4个方向)的跑步动作序列图。假如想获取一个姿态的位图,可利用Canvas的上下文2D对象的drawImage(image, sourceX, sourceY, sourceWidth,sourceHeight,destX,destY,destWidth,destHeight)方法将源位图上某个区域(sourceX,sourceY,sourceWidth,sourceHeight)复制到目标区域的(destX,destY)坐标处,显示大小为(destWidth,destHeight)。

 

■ 图1 一个方向的跑步动作序列

【例1】实现从跑步动作序列Snap1.jpg文件中截取的第3个动作(帧)。

分析:在Snap1.jpg文件中,每个人物动作的大小为60×80px,所以截取源位图的sourceX=120,sourceY=0,sourceWidth=60,sourceHeight=80就是第3个动作(帧)。

<canvas id="myCanvas" height=250 width=250>您的浏览器不支持 canvas。</canvas>
<script type="text/javascript">
function draw()
{
  var canvas=document.getElementById("myCanvas"); // 获取网页中的canvas对象
  var ctx = canvas.getContext("2d"); //获取canvas对象的上下文
  var imageObj = new Image(); // 创建图像对象
  imageObj.src = "Snap1.jpg";
  imageObj.onload = function(){
      //从原图(120, 0)位置开始截取中间一块宽60*高80的区域,原大小显示在屏幕(0,0)处
      ctx.drawImage(imageObj, 120, 0, 60, 80, 0, 0, 60, 80);
     };
}
window.addEventListener("load", draw, true);
</script>

 例1的运行结果如图2所示,在页面上仅仅显示第3个动作。

 ■ 图2 静态显示第3个动作

02、游戏人物的跑步动画

【例2】实现游戏人物的跑步动画。

首先定义一个Canvas元素,画布的长度和宽度都是300px,代码如下:

<!DOCTYPE html>
<html>
  <head>
    <title>HTML5 Canvas实现游戏人物的跑步动画</title>
  </head>
  <body>
    <canvas id="myCanvas" width="300" height="300"></canvas>
  </body>
</html>

 在JavaScript代码中定义一个Image对象,用于显示Snap1.jpg。然后定义一个init()函数,初始化Image对象,并设置定时器,代码如下:

<script type="text/javascript"> 
    var imageObj = new Image(); // 创建图像对象
    var x =300;
    var n =0; // 计数器
    function init(){
      imageObj.src = 'Snap1.jpg';
      imageObj.onload = function(){
         setInterval(draw,100);// 定时器,每0.1秒执行一次draw()函数
      };
// 此处省略draw()函数的代码
   window.addEventListener("load", init, true);
  </script>

 

使用了定时器,每隔100毫秒就会在Snap1.jpg图片截取一张60×80px大小的小图并绘制出来,且每次向左移15px,直到最左端时重新从右侧开始,不停循环,就可见游戏人物在屏幕上不停地奔跑。

下面分析draw()函数的实现。例5-14中仅仅显示人物的第三个动作,而为了实现动画,需要clearRect(x,y,width,height)不断清除先前绘制的动作图形,再绘制后续的动作。所以需要一个计数器n,记录当前绘制到第几动作(帧)了。

function draw()
    {
        var canvas=document.getElementById("myCanvas"); // 获取网页中的canvas对象
        var ctx = canvas.getContext("2d"); //获取canvas对象的上下文
           ctx.clearRect(0,0,300,300); // 清除canvas画布
           //从原图(60*n)位置开始截取中间一块宽60*高80的区域,显示在屏幕(x,0)处
           ctx.drawImage(imageObj, 60*n, 0, 60, 80, x, 0, 60, 80);
           if(n>=8){
              n=0;
           }else{
              n++;
           }
           if(x>=0){
              x=x-30; //前移30像素
           }else{
              x=300; //回到右侧
           }
    }

 例2的运行结果是一个游戏人物不停且重复地从右侧跑到左侧的动画。

03、雪花飘落动画

在HTML5中制作雪花飘落动画,需要使用Canvas画圆arc(x,y,r,start,stop)以构成圆形雪花;网页加载时,需要生成一定数量(如200个)的不同半径及位置的雪花,故半径、坐标为随机数;雪花在飘落过程中,其半径不变,坐标在一定幅度内变化。

制作雪花飘落动画,首先产生一个画布Canvas。

<script type="text/javascript"> 
        var canvas=document.getElementById("myCanvas")
        var context = canvas.getContext("2d"); //2d即指二维平面
        var w =window.innerWidth
        var h =window.innerHeight
        canvas.width = w;
        canvas.height =h;

 

然后再生成200个雪花的对象组。当生成雪花时,每个雪花半径、位置都不同。如果把每个雪花当成一个对象,那么这个对象的属性就包含半径、坐标(X、Y)。一个雪花对象可以写成var snowOject={x: 1,y: 10,r: 5},代表一个坐标为(1,10)、半径为5的圆形雪花。

注意/

本示例中由于半径和坐标都为随机数,故使用Math.random()方法分别为200个雪花生成半径、坐标(X、Y);动画有200个雪花,所以为了方便后面操作,就用一个数组保存这200个雪花对象。

var count =200 //雪花的个数
        var snows=[] //雪花对象数组
        for (var i=0 ; i< count;i++){
            snows.push({
                x:Math.random()*w, //Math.random()用于生成0~1的随机数
                y:Math.random()*h,
                r:Math.random()*5,
            })
        }

 在绘制时设置雪花的样式。

function draw(){
            context.clearRect(0,0,w,h)
            context.beginPath()
            for(var i=0; i<count;i++){
                var snow = snows[i];
                context.fillStyle ="rgb(255,255,255)" //设置雪花的样式
                context.shadowBlur=10;
                context.shadowColor="rgb(255,255,255)";
                //moveTo 移动到指定的坐标
                context.moveTo(snow.x,snow.y);
                // 使用canvas arc()创建一个圆形
                 //x,y,r:圆的中心的x坐标和y坐标,r为半径
                //0,Math.PI * 2起始弧度和结束弧度
                context.arc(snow.x,snow.y,snow.r,0,Math.PI * 2);
            }
            context.fill(); //画布填充
            move();
        }

 move()函数让雪花它们飘动起来,就是雪花不停地移动位置。超出页面则重新设置位置和雪花大小。

function move(){
            for (var i=0;i<count;i++){
                var snow =snows[i];
                snow.y +=(7-snow.r)/10 //从上往下飘落
                snow.x+=((5-snow.r)/10)//从左到右飘落
                if(snow.y>h){
                    snows[i]={
                        x:Math.random()*w,
                        y:Math.random()*h,
                        r:Math.random()*5,
                    }
                }
            }
        }

 最后设置刷新频率。

setInterval(draw,10); //每10毫秒刷新一次
    </script>

 页面中定义一个Canvas元素,画布的长度和宽度都是300px。

<body>
    <canvas id="myCanvas" height=500 width=500 class="my">您的浏览器不支持 canvas。</canvas>
</body>

 例子的运行结果如图3所示。

 ■ 图3 雪花飘落

更多推荐

民安智库(第三方市场调查公司)开展景区游客满意度调查

为什么要开展景区游客满意度调查景区的经营管理是一个动态的过程,需要不定期的地进行调查,让管理者了解景区管理的不足之处,并不断地改善和提高管理水平,以保证经营目标的顺利完成。景区旅游要想真正地成为可持续发展的经济产业,就不能忽视游客的体验感受情况,这是因为旅游景区游客满意度的变化能直接反映出景区管理中存在的问题。现在国内

Twitter图片数据优化的细节

Twitter个人数据优化:吸引更多关注和互动头像照片在Twitter上,头像照片是最快识别一个账号的方法之一。因此,请务必使用公司的标志或与品牌相关的图片。建议尺寸为400x400像素。为了建立强大的品牌形象和一致性,强烈建议在所有社交媒体上使用相同的头像照片。您的Twitter简介是针对企业的160个字符的描述。它

数据分析与可视化项目技术参考

🙌秋名山码民的主页😂oi退役选手,Java、大数据、单片机、IoT均有所涉猎,热爱技术,技术无罪🎉欢迎关注🔎点赞👍收藏⭐️留言📝获取源码,添加WX目录1.考核的主要内容2.具体实现流程3.技术参考3.1数据获取3.2数据清洗与处理3.3数据存储到Mysql3.4网站开发3.4.1登录页面3.4.2数据可视化

数据库数据恢复-SQL SERVER数据库分区被格式化的数据恢复方案

SQLSERVER数据库故障类型:1、SQLSERVER数据库文件被删除。2、SQLSERVER数据库所在分区格式化。3、SQLSERVER数据库文件大小变为“0”。4、使用备份还原数据库时覆盖原数据库。SQLSERVER数据库故障原因:1、人为误操作。2、文件系统损坏,设备自动做磁盘检测。SQLSERVER数据库故障

【Spring Boot】Spring Boot源码解读与原理剖析

这里写目录标题前言精进SpringBoot首选读物“小册”变“大书”,彻底弄懂SpringBoot全方位配套资源,学不会来找我!技术新赛道,2023领先抢跑前言承载着作者的厚望,掘金爆火小册同名读物《SpringBoot源码解读与原理剖析》正式出书!本书前身是掘金社区销量TOP的小册——《SpringBoot源码解读与

shell循环和函数

目录1.for循环2.while循环3.until循环4.函数5.特殊流程控制语句1.for循环for循环是固定循环,也就是在循环时就已经知道需要进行几次的循环,有事也把for循环成为计数循环。for的语法如下两种:语法一for变量in值1值2值3…(可以是一个文件等)do程序done这种语法中for循环的次数,取决于

ARTS 打卡 第二周,按部就班

引言认识三掌柜的想必都知道,我持续创作技术博客已经有6年时间了,固定每个月发布不少于6篇博文。同时,自己作为一名热爱分享的开发者,像ARTS这样的活动自然少不了我。由于我是打算挤在一起分享,之前都是做了本地文档记录,所以直接把内容整合起来即可,那么接下来就开启我的第二周打卡咯。Algorithm本周分享的算法题是力扣(

400电话怎么办理(申请开通)

申请开通400电话是一项相对简单的过程,只需按照以下步骤进行操作即可。第一步,选择400电话服务提供商。在市场上有很多公司提供400电话服务,您可以根据自己的需求和预算选择适合的服务商。可以通过搜索引擎、咨询朋友或者查看相关论坛等方式获取一些可靠的服务商名单。第二步,了解服务商的费用和服务内容。不同的服务商提供的费用和

消息中间件大揭秘:选择之前你必须知道的关键信息

Hello大家好!我是小米,很高兴再次和大家见面!今天的话题非常精彩,我们将深入探讨消息中间件,并了解一些常见的消息队列:RabbitMQ、RocketMQ、Kafka以及Redis。如果你正在准备面试,或者只是对这些消息中间件感兴趣,那么这篇文章一定会对你有所帮助。什么是消息中间件?首先,让我们来了解一下什么是消息中

RTU遥测终端机,提升水资源管理效率!

2023年水利部发布的《关于推进水利工程配套水文设施建设的指导意见》,强调要聚焦保障水利工程安全高效运行、完善风险监测预警体系、提高防灾减灾能力和水资源水环境水生态综合治理能力、推动新阶段水利高质量发展的要求,加强水利工程配套水文设施建设。遥测终端机在现代水利行业中扮演着重要的角色,可以有效地监测、收集和传输水文数据,

JVM——11.JVM小结

这篇文章我们来小结一下JVMJVM,即java虚拟机,是java代码运行时的环境。我们从底层往上层来说,分别是硬件部分,操作系统,JVM,jre,JDK,java代码。JVM是直接与操作系统打交道的。JVM也是java程序一次编到处运行的主要原因。JVM主要就是讲了一句话,即“Studenta=newStudent()

热文推荐