HTML5的誕生給web前端界帶來了不小轟動,像什麼動畫旋轉、圖片滑塊、圖片輪播等等這些3D特效,也引起了很多朋友想要學習HTML5的好奇心。最近我一直在作canvas動畫效果,發現canvas這個東西作動畫不是不能夠。相對於flash,它太底層。若是有給力的編輯器或者給力的框架的話,它就能發揮出更大的威力。html
小編特意找了一個技術大神總結的框架,在此分享給你們 教程詳解:http://edu.51cto.com/course/courseList/id-86.html
分幾個章節來說述我這個小動畫框架的實現:前端
1.通用類的提取:動畫對象與幀對象 web
2.靈與肉的結合:便於拆卸的運動方程 canvas
3.進度條的實現:canvas的圖片預加載 數組
4.demo測試:經過一個demo測試框架 框架
這一節咱們先來講說通用類的提取。異步
其實上一篇文章我已經用到了這種從flash借鑑來的思路:一個動畫對象(相似flash中的元件),一個幀對象(相似flash中的幀)。動畫就是在不斷在當前幀上繪製每一個動畫對象來實現的。有了這兩個對象,再加上一些運動方法,咱們就能夠構建出動畫來。編輯器
首先咱們先來看看動畫對象Aniele:學習
01 | /* 瞭解更多 |
02 | *Aniele動畫對象 |
03 | *全部動畫對象的始祖 |
04 | */ |
05 | varAniele=function(){ |
06 | this.img=newImage(); |
07 | //定義動畫對象位置 |
08 | this.loca={ |
09 | x:300, |
10 | y:300 |
11 | } |
12 | //定義動畫對象的大小(能夠實現縮放) |
13 | this.dw; |
14 | this.dh; |
15 | //動畫對象的速度屬性 |
16 | this.speed={ |
17 | x:0, |
18 | y:0 |
19 | } |
20 | //設置對象的透明度 |
21 | this.alpha=1; |
22 | //設置圖像翻轉,1爲不翻轉,-1爲翻轉 |
23 | this.scale={ |
24 | x:1, |
25 | y:1 |
26 | } |
27 | //定動畫對象的運動方法庫 |
28 | this.motionFncs=[]; |
29 | } |
30 | Aniele.prototype={ |
31 | //添加運動方法 |
32 | addMotionFnc:function(name,fnc) { |
33 | this.motionFncs[name]=fnc; |
34 | }, |
35 | //刪除運動方法 |
36 | deleMotionFnc:function(name){ |
37 | this.motionFncs[name]=null; |
38 | }, |
39 | //遍歷運動方法庫裏的全部運動方法 |
40 | countMotionFncs:function() { |
41 | for(vari=0; i |
42 | if(this.motionFncs[i]==null) |
43 | continue; |
44 | this.motionFncs[i].call(this); |
45 | } |
46 | }, |
47 | //把本身繪製出來的方法,包括功能:水平翻轉 |
48 | draw:function(canvas,ctx){ |
49 | //存儲canvas狀態ctx.save(); |
50 | //實現透明度的改變 |
51 | ctx.globalAlpha=this.alpha; |
52 | //實現水平豎直翻轉,定義drawImage的兩個位置參數dx,dy |
53 | vardx=this.loca.x; |
54 | vardy=this.loca.y; |
55 | if(this.scale.x!=1||this.scale.y!=1){ |
56 | if(this.scale.x<0){ |
57 | console.log(this.img.width) |
58 | dx=canvas.width-this.loca.x-this.img.width; |
59 | ctx.translate(canvas.width,1); |
60 | ctx.scale(this.scale.x,1); |
61 | } |
62 | if(this.scale.y<0){ |
63 | dy=canvas.height-this.loca.y-this.img.height; |
64 | ctx.translate(1,canvas.height); |
65 | ctx.scale(1,this.scale.y); |
66 | } |
67 | } |
68 | if(this.dw==null) |
69 | this.dw=this.img.width; |
70 | if(this.dh==null) |
71 | this.dh=this.img.height; |
72 | //畫出對象 |
73 | ctx.drawImage(this.img,dx,dy,this.dw,this.dh); |
74 | //恢復canvas狀態ctx.restore(); |
75 | } |
76 | } |
動畫對象的主要屬性:測試
this.img=newImage();咱們引入一張圖片,依附在動畫對象上;
this.loca.x等等;圖片的大小位置透明度等等,便於繪圖時調用;
this.motionFncs=[];這個比較關鍵,咱們給動畫對象定義一個運動方法庫,把動畫對象的運動規則都放在這個運動方法庫中統一管理(每一個動畫對象都有本身的運動方法庫);
動畫對象的主要方法:
addMotionFnc: 爲動畫對象的運動方法庫中添加一個運動方法;
deleMotionFnc:爲動畫對象的運動方法庫中刪除一個運動方法;
countMotionFncs:爲動畫對象遍歷運動方法庫中的全部運動方法;
draw:把動畫對象畫在畫布上,這裏咱們會把畫布做爲參數傳到這個方法裏面去,便於繪圖;
在draw方法裏,我封裝了一些對圖像的簡單操做,這些操做在動畫中會常常用到:透明,縮放和翻轉。
有了這個,咱們就好似得到了flash裏的一個元件,咱們能夠經過修改它的屬性來隨意改變它。
那麼幀對象呢?
幀對象肩負着渲染的任務,而且管理全部動畫對象;
幀對象的主要屬性:
this.aniEles=[];用來存儲當前畫布上全部動畫實例的數組;
你們用過canvas載入圖片的應該知道,因爲圖片的異步載入,動畫過程當中圖片會出現閃爍的現象,爲了不這種現象,我採用了雙緩衝。
首前後臺建立一個畫布:
this.backBuffer=document.('canvas');
this.backBuffer.width=this.canvas.width;
this.backBuffer.height=this.canvas.height;
this.backBufferctx=this.backBuffer.getContext('2d');
咱們全部繪製命令都執行在這個後臺畫布上,最後把後臺畫布畫在前臺畫布上:
this.ctx.drawImage(this.backBuffer,0,0);
這種先把圖繪在後臺畫布,再把後臺畫布複製到前臺的方法就叫作雙緩衝技術。
幀屬性的主要方法:
int:用於初始化畫布;
begin:開始動畫渲染的方法;
render:主渲染的方法;
addAniEle:爲當前幀添加動畫對象;
deleAniEle:爲當前幀刪除動畫;
咱們利用幀對象的流程是:先爲當前幀添加動畫對象,而後讓當前幀開始渲染。
具體學習參照:http://edu.51cto.com/course/courseList/id-86.html