如何用HTML5画布制作3D动画效果

HTML5的诞生给web前端世界带来了不小的轰动。动画旋转、图片滑块、图片轮播等等3D特效也引起了很多想学习HTML5的朋友的好奇心。最近一直在做画布动画特效,发现画布动画化也不是不可以。和flash比起来,太低级了。如果有一个强大的编辑器或者强大的框架,就能发挥更大的作用。

于是我决定自己写一个简单的动画框架,以便更方便地构造一些动画效果。

我将分几章讲述我的小动画框架的实现:

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:为当前帧添加动画对象;

删除当前帧的动画;

我们使用帧对象的过程是:先给当前帧添加动画对象,然后让当前帧开始渲染。

河南新华电脑学院网络运营协会为您解答。