如何用HTML5画布制作3D动画效果
于是我决定自己写一个简单的动画框架,以便更方便地构造一些动画效果。
我将分几章讲述我的小动画框架的实现:
1.通用类的提取:动画对象和帧对象
2.灵与肉的结合:一个易于分解的运动方程
3.进度条的实现:预加载画布的图片。
4 .演示测试:通过一个演示测试框架。
本节先说一般类的提取。
事实上,我在上一篇文章中已经使用了从flash中借用的这个思想:一个动画对象(类似于flash中的一个组件)和一个帧对象(类似于flash中的一个帧)。动画是通过在当前帧上不断绘制每个动画对象来实现的。有了这两个对象和一些运动方法,我们就可以构建一个动画了。
首先,我们来看看动画对象Aniele:
/*
*Aniele动画对象
*所有动画对象的祖先。
*/
varAniele=function(){
this . img = new image();
//定义动画对象位置
this.loca={
x:300,
y:300
}
//定义动画对象的大小(可以缩放)
this.dw
this.dh
//动画对象的速度属性
this.speed={
x:0,
y:0
}
//设置对象的透明度。
this . alpha = 1;
//设置图像翻转,1表示不翻转,-1表示翻转。
this.scale={
x:1,
y:1
}
//定义动画对象的运动方法库。
this . motionfncs =[];
}
Aniele.prototype={
//添加一个运动方法
addMotionFnc:function(name,fnc) {
this . motionfncs[name]= fnc;
},
//删除运动方法
deleMotionFnc:函数(名称){
this . motionfncs[name]= null;
},
//遍历运动方法库中的所有运动方法。
countMotionFncs:function() {
for(vari = 0;我
if(this.motionFncs[i]==null)
继续;
this.motionFncs[i]。叫(这个);
}
},
//自己画的方法,包括功能:水平翻转。
draw:函数(canvas,ctx){
//存储画布状态CTX . save();
//更改透明度。
CTX . global alpha = this . alpha;
//实现水平和垂直翻转,定义drawImage的两个位置参数dx,dy。
vardx = this . loca . x;
vardy = this . loca . y;
如果(this.scale.x!=1||this.scale.y!=1){
if(this . scale . x & lt;0){
控制台. log(this.img.width)
dx = canvas . width-this . loca . x-this . img . width;
ctx.translate(canvas.width,1);
ctx.scale(this.scale.x,1);
}
if(this . scale . y & lt;0){
dy = canvas . height-this . loca . y-this . img . height;
ctx.translate(1,canvas . height);
ctx.scale(1,this . scale . y);
}
}
if(this.dw==null)
this . dw = this . img . width;
if(this.dh==null)
this . DH = this . img . height;
//绘制一个对象
ctx.drawImage(this.img,dx,dy,this.dw,this . DH);
//恢复画布状态CTX . Restore();
}
}
动画对象的主要属性:
this . img = new image();我们引入一张图片,并将其附加到动画对象上;
This.loca.x等等;图片的大小和位置的透明度等。,方便绘图时调用;
this . motionfncs =[];这才是重点。我们为动画对象定义了一个运动方法库,将动画对象的所有运动规则都放在这个运动方法库中进行统一管理(每个动画对象都有自己的运动方法库)。
动画对象的主要方法:
AddMotionFnc:将运动方法添加到动画对象的运动方法库中;
DeleMotionFnc:从动画对象的运动方法库中删除一个运动方法;
CountMotionFncs:遍历动画对象的运动方法库中的所有运动方法;
Draw:在画布上绘制动画对象,这里我们将画布作为参数传递给这个方法,方便绘制;
在draw方法中,我封装了一些在动画中经常用到的对图像的简单操作:透明、缩放和翻转。
有了这个,我们就好像在flash里得到了一个组件,可以通过修改它的属性来随意改变它。
框架对象呢?
帧对象承担渲染和管理所有动画对象的任务:
/*
*渲染渲染对象
*管理所有动画对象和渲染。
*参数:canvas对象,canvas上下文*/varrender = function (canvas,CTX) {
//介绍画布
this.canvas =画布;
this.ctx = ctx
//创建缓冲画布
this.backBuffer=document。(‘画布’);
this . back buffer . width = this . canvas . width;
this . back buffer . height = this . canvas . height;
this . backbuffertx = this . back buffer . get context(' 2d ');
//所有动画对象
this . anieles =[];
}
Render.prototype={
//初始化画布int
int:function() {
clear interval(this . Sint);
this.ctx.clearRect(0,0,this.canvas.width,this . canvas . height);
this . backbuffertx . clear rect(0,0,this.backBuffer.width,this . back buffer . height);
},
//设置为开始呈现
begin:function() {
this.lastFrame=(newDate())。getTime();
this . Sint = setInterval((function(progra){
return function(){ progra . render();}
})(这个),第二);
},
//主呈现方法
render:function() {
//清除画布上的历史帧并缓存画布。
this.ctx.clearRect(0,0,this.canvas.width,this . canvas . height);
this . backbuffertx . clear rect(0,0,this.backBuffer.width,this . back buffer . height);
//保存当前实时输出帧率this.ftp
this.nowFrame=(newDate())。getTime();
this . FTP = 1000/(this . now frame-this . last frame);
this . last frame = this . now frame;
//调用每个动画对象的motion方法。
for(vari = 0;我
if(this.aniEles[i]==null)
继续;
this.aniEles[i]。countMotionFncs();
//在背景缓冲区画布上绘制对象
this.aniEles[i]。draw(this.backBuffer,this . backbuffertx);
}
//将背景对象绘制到前景。
this . CTX . draw image(this . back buffer,0,0);
},
//添加动画对象
addAniEle:函数(名称,aniEle) {
this . anieles[name]= aniEle;
},
//删除动画对象
deleAniEle:函数(名称){
this . anieles[name]= null;
}
}
框架对象的主要属性:
this . anieles =[];用于存储当前画布上所有动画实例的数组;
用过canvas加载图片的人都应该知道,由于图片加载的异步性,动画时图片会有闪烁。为了避免这种现象,我采用了双缓冲。
首先,在背景中创建一个画布:
this.backBuffer=document。(‘画布’);
this . back buffer . width = this . canvas . width;
this . back buffer . height = this . canvas . height;
this . backbuffertx = this . back buffer . get context(' 2d ');
我们所有的绘制命令都在这个背景画布上执行,最后在前景画布上绘制背景画布:
this . CTX . draw image(this . back buffer,0,0);
这种先把画面画在背景画布上,再把背景画布复制到前台的方法,叫做双缓冲技术。
框架属性的主要方法:
Int:用于初始化画布;
Begin:开始动画渲染的方法;
渲染:主渲染的方法;
AddAniEle:为当前帧添加动画对象;
删除当前帧的动画;
我们使用帧对象的过程是:先给当前帧添加动画对象,然后让当前帧开始渲染。
河南新华电脑学院网络运营协会为您解答。