HTML5正在變得越來越流行。在這個移動設備日益增長的時代,對來自Adobe的Flash插件的改造需求也正在快速增長。因為就在最近,Adobe宣布Flash將不再支持移動設備。這意味著,Adobe自身也認為對移動設備來講HTML5是一項重要的技術。而桌面系統的改變也是遲早的事。
HTML的一大劣勢就是對於多媒體技術支持的缺乏。在HTML中,你無法直接顯示一個視頻或在屏幕上繪畫。在HTML5中,隨著<video>與<canvas>元素的引進。這些元素給予開發者直接使用“純粹的”HTML來實現多媒體技術的可能性——僅需要寫一些Javascript代碼來配合HTML。在多媒體技術中,有一個基本的技術應該被支持——動畫。在HTML5中,有不少方式能夠實現該功能。
在這篇文章中,我僅將最新的<canvas>元素與即將到來的CSS3動畫技術進行比較。其他的可能性包括DOM元素或SVG元素的創建和動畫。這些可能性將不在本文中進行討論。從開始就應該注意到canvas技術在當前發布的大部分主流浏覽器都給予了支持,而CSS3動畫僅在最新的FireFox與Chrome浏覽器中才有實現的可能,下一個版本的IE也將提供對CSS3動畫的支持。(所以本文中所有演示代碼的效果,在Win 7系統下當前最新版的Chrome浏覽器中都可實現,但在其他操作系統與其他浏覽器中,並不一定能看到所有演示代碼的效果)。
演示地址:http://www.muu.cc/html5/xiaoche
下載地址:
免費下載地址在 http://linux.linuxidc.com/
用戶名與密碼都是www.linuxidc.com
具體下載目錄在 /2012年資料/4月/22日/HTML5 實現小車動畫效果/
這裡我選擇了一個比較簡單的動畫:
PS:由於顯卡、錄制的幀間隔,以及可能你電腦處理器的原因,播放過程可能有些不太流暢或者失真!
分三種方式實現:
(1) canvas元素結合JS
(2) 純粹的CSS3動畫(暫不被所有主流浏覽器支持,比如IE)
(3) CSS3結合Jquery實現
知道如何使用CSS3動畫比知道如何使用<canvas>元素更重要:因為浏覽器能夠優化那些元素的性能(通常是他們的樣式,比如CSS),而我們使用canvas自定義畫出來的效果卻不能被優化。原因又在於,浏覽器使用的硬件主要取決於顯卡的能力。目前,浏覽器沒有給予我們直接訪問顯卡的權力,比如,每一個繪畫操作都不得不在浏覽器中先調用某些函數。
讓我們從Canvas開始
HTML代碼:
- <html>
- <head>
- <meta charset="UTF-8" />
- <title>Animation in HTML5 using the canvas element</title>
- </head>
- <body onload="init();">
- <canvas id="canvas" width="1000" height="600">Your browser does not support the <code><canvas></code>-element.Please think about updating your brower!</canvas>
- <div id="controls">
- <button type="button" onclick="speed(-0.1);">Slower</button>
- <button type="button" onclick="play(this);">Play</button>
- <button type="button" onclick="speed(+0.1)">Faster</button>
- </div>
- </body>
- </html>
JS代碼:
定義一些變量:
- var dx=5, //當前速率
- rate=1, //當前播放速度
- ani, //當前動畫循環
- c, //畫圖(Canvas Context)
- w, //汽車[隱藏的](Canvas Context)
- grassHeight=130, //背景高度
- carAlpha=0, //輪胎的旋轉角度
- carX=-400, //x軸方向上汽車的位置(將被改變)
- carY=300, //y軸方向上汽車的位置(將保持為常量)
- carWidth=400, //汽車的寬度
- carHeight=130, //汽車的高度
- tiresDelta=15, //從一個輪胎到最接近的汽車底盤的距離
- axisDelta=20, //汽車底部底盤的軸與輪胎的距離
- radius=60; //輪胎的半徑
為了實例化汽車canvas(初始時被隱藏),我們使用下面的自執行的匿名函數
- (function(){
- var car=document.createElement('canvas'); //創建元素
- car.height=carHeight+axisDelta+radius; //設置高度
- car.width=carWidth; //設置寬度
- w=car.getContext('2d');
- })();
點擊“Play”按鈕,通過定時重復執行“畫汽車”操作,來模擬“幀播放”功能:
- function play(s){ //參數s是一個button
- if(ani){ //如果ani不為null,則代表我們當前已經有了一個動畫
- clearInterval(ani); //所以我們需要清除它(停止動畫)
- ani=null;
- s.innerHTML='Play'; //重命名該按鈕為“播放”
- }else{
- ani=setInterval(drawCanvas,40); //我們將設置動畫為25fps[幀每秒],40/1000,即為二十五分之一
- s.innerHTML='Pause'; //重命名該按鈕為“暫停”
- }
- }
加速,減速,通過以下方法,改變移動距離的大小來實現:
- function speed(delta){
- var newRate=Math.max(rate+delta,0.1);
- dx=newRate/rate*dx;
- rate=newRate;
- }
頁面加載的初始化方法:
- //init
- function init(){
- c=document.getElementById('canvas').getContext('2d');
- drawCanvas();
- }
主調方法:
- function drawCanvas(){
- c.clearRect(0,0,c.canvas.width, c.canvas.height); //清除Canvas(已顯示的),避免產生錯誤
- c.save(); //保存當前坐標值以及狀態,對應的類似“push”操作
-
- drawGrass(); //畫背景
- c.translate(carX,0); //移動起點坐標
- drawCar(); //畫汽車(隱藏的canvas)
- c.drawImage(w.canvas,0,carY); //畫最終顯示的汽車
- c.restore(); //恢復Canvas的狀態,對應的是類似“pop”操作
- carX+=dx; //重置汽車在X軸方向的位置,以模擬向前走
- carAlpha+=dx/radius; //按比例增加輪胎角度
-
- if(carX>c.canvas.width){ //設置某些定期的邊界條件
- carX=-carWidth-10; //也可以將速度反向為dx*=-1;
- }
- }
畫背景:
- function drawGrass(){
- //創建線性漸變,前兩個參數為漸變開始點坐標,後兩個為漸變結束點坐標
- var grad=c.createLinearGradient(0,c.canvas.height-grassHeight,0,c.canvas.height);
- //為線性漸變指定漸變色,0表示漸變起始色,1表示漸變終止色
- grad.addColorStop(0,'#33CC00');
- grad.addColorStop(1,'#66FF22');
- c.fillStyle=grad;
- c.lineWidth=0;
- c.fillRect(0,c.canvas.height-grassHeight,c.canvas.width,grassHeight);
-
- }
畫車身:
- function drawCar(){
- w.clearRect(0,0,w.canvas.width,w.canvas.height); //清空隱藏的畫板
- w.strokeStyle='#FF6600'; //設置邊框色
- w.lineWidth=2; //設置邊框的寬度,單位為像素
- w.fillStyle='#FF9900'; //設置填充色
- w.beginPath(); //開始繪制新路徑
- w.rect(0,0,carWidth,carHeight); //繪制一個矩形
- w.stroke(); //畫邊框
- w.fill(); //填充背景
- w.closePath(); //關閉繪制的新路徑
- drawTire(tiresDelta+radius,carHeight+axisDelta); //我們開始畫第一個輪子
- drawTire(carWidth-tiresDelta-radius,carHeight+axisDelta); //同樣的,第二個
-
- }
畫輪胎:
- function drawTire(x,y){
- w.save();
- w.translate(x,y);
- w.rotate(carAlpha);
- w.strokeStyle='#3300FF';
- w.lineWidth=1;
- w.fillStyle='#0099FF';
- w.beginPath();
- w.arc(0,0,radius,0,2*Math.PI,false);
- w.fill();
- w.closePath();
- w.beginPath();
- w.moveTo(radius,0);
- w.lineTo(-radius,0);
- w.stroke();
- w.closePath();
- w.beginPath();
- w.moveTo(0,radius);
- w.lineTo(0,-radius);
- w.stroke();
- w.closePath();
- w.restore();
-
- }
由於原理簡單,並且代碼中作了詳細注釋,這裡就不一一講解!