其中最大的限制就是Canvas元素中的圖形一經(jīng)繪制就不會(huì)改變,除非你要人為改變它。如果我們需要改變Canvas元素中繪制的圖形,我們就必須先重繪相應(yīng)的圖形。重繪復(fù)雜的圖形會(huì)花費(fèi)掉很多的時(shí)間,因此動(dòng)畫(huà)效果也將受限于電腦的速度。
實(shí)現(xiàn)動(dòng)畫(huà)的原理
1、重繪canvas
除非你會(huì)畫(huà)一些能夠填滿整個(gè)canvas的圖形(例如背景圖),否則你有必要**先前繪制的所有圖形。而最簡(jiǎn)單的方法是使用clearRect方法。
2、保存canvas狀態(tài)
如果你更動(dòng)了任何一個(gè)會(huì)影響到canvas狀態(tài)的設(shè)定(樣式、變形等等),并且希望能夠確保每一次繪制畫(huà)格時(shí)都是原本的狀態(tài),你就需要保存canvas狀態(tài)。
3、繪制移動(dòng)中的圖形
在這一步驟里才真正畫(huà)出需要移動(dòng)的圖形。
4、讀取canvas狀態(tài)
如果你先前保存過(guò)Canvas的狀態(tài),就先在畫(huà)新的圖形之前讀取之前的狀態(tài)。
動(dòng)畫(huà)的操控
圖形是以直接使用canvas方法或調(diào)用自訂的函數(shù)所繪制的。在正常情況下,當(dāng)JavaScript執(zhí)行完成時(shí),我們就能看見(jiàn)呈現(xiàn)在canvas上的結(jié)果。
我們需要一個(gè)方法,能在一段時(shí)間內(nèi)循環(huán)執(zhí)行我們的繪圖函數(shù)。有兩個(gè)方法可操控這樣的動(dòng)畫(huà)。首先,這里有setInterval和setTimeout函數(shù),可用來(lái)在指定的時(shí)間內(nèi)調(diào)用特定的函數(shù)。
- setInterval(animateShape,500);
- setTimeout(animateShape,500);
如果你不需要和用戶(hù)互動(dòng),就最好使用setInterval函數(shù),他會(huì)重復(fù)執(zhí)行預(yù)先準(zhǔn)備好的代碼。在上面的例子里,animateShape函數(shù)是每500毫秒(一秒的一半)執(zhí)行一次。setTimeout函數(shù)只會(huì)在設(shè)定好的時(shí)間點(diǎn)上執(zhí)行一次。
第二個(gè)方法是我們可以利用用戶(hù)的輸入來(lái)操控。如果我們想要制作游戲,我們可以使用鍵盤(pán)或滑鼠的事件來(lái)操控動(dòng)畫(huà)。只需設(shè)定事件接收器(eventListener),我們就能捕捉任何的使用者動(dòng)作,并執(zhí)行我們的動(dòng)畫(huà)函數(shù)。
動(dòng)畫(huà)范例
在這個(gè)范例中,我們使用setInterval函數(shù)來(lái)操控動(dòng)畫(huà),使小型的太陽(yáng)系模擬系統(tǒng)動(dòng)起來(lái)。
- var sun = new Image();
- var moon = new Image();
- var earth = new Image();
- function init(){
- sun.src = 'images/sun.png';
- moon.src = 'images/moon.png';
- earth.src = 'images/earth.png';
- setInterval(draw,100);
- }
-
- function draw() {
- var ctx = document.getElementById('canvas').getContext('2d');
-
- ctx.globalCom**iteOperation = 'destination-over';
- ctx.clearRect(0,0,300,300); // **canvas
-
- ctx.fillStyle = 'rgba(0,0,0,0.4)';
- ctx.strokeStyle = 'rgba(0,153,255,0.4)';
- ctx.save();
- ctx.translate(150,150);
-
- // 地球
- var time = new Date();
- ctx.rotate( ((2*Math.PI)/60)*time.getSeconds() +
- ((2*Math.PI)/60000)*time.getMilliseconds() );
- ctx.translate(105,0);
- ctx.fillRect(0,-12,50,24); // 陰影
- ctx.drawImage(earth,-12,-12);
-
- // 月球
- ctx.save();
- ctx.rotate( ((2*Math.PI)/6)*time.getSeconds() +
- ((2*Math.PI)/6000)*time.getMilliseconds() );
- ctx.translate(0,28.5);
- ctx.drawImage(moon,-3.5,-3.5);
- ctx.restore();
-
- ctx.restore();
-
- ctx.beginPath();
- ctx.arc(150,150,105,0,Math.PI*2,false); // 地球軌道
- ctx.stroke();
-
- ctx.drawImage(sun,0,0,300,300);
- }
引用MOZILLA DEVELOPER NETWORK
轉(zhuǎn)自houoop
【網(wǎng)站聲明】本站除付費(fèi)源碼經(jīng)過(guò)測(cè)試外,其他素材未做測(cè)試,不保證完整性,網(wǎng)站上部分源碼僅限學(xué)習(xí)交流,請(qǐng)勿用于商業(yè)用途。如損害你的權(quán)益請(qǐng)聯(lián)系客服QQ:2655101040 給予處理,謝謝支持。