HTML5 Canvas 動畫。
10. 動畫
要做動畫就要有一個固定的時間迴圈,不斷地重覆執行把每個影格中的影像畫出來,最常用的大概就是 setTimeout 了。但現在有 requestAnimFrame() 方法,由瀏覽器實作專門用來執行動畫。它的固定寫法如下:
window.requestAnimFrame = (function(callback) {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 1000 / 60);
};
})();
整個動畫的程式碼基本架構:
<script>
window.requestAnimFrame = (function(callback) {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 1000 / 60);
};
})();
window.onload = function() {
init();
loop();
};
//在這裡建立要用到的變數
var canvas, context;
//初始化
function init() {
canvas = document.getElementById("myCanvas");
context = canvas.getContext("2d");
}
//時間迴圈
function loop() {
requestAnimFrame(loop);
update();
draw();
}
//執行繪圖
function draw() {
//清除整個畫布
context.clearRect(0, 0, canvas.width, canvas.height);
//以新的座標畫圖
}
//更新
function update(){
}
</script>
清除畫布 clearRect 的用意,是把前一個畫面給清除掉。整個步驟就是,計算位置->畫圖->清除->計算位置->畫圖->清除->...如此循環。update() 函式就是用來計算下一個應該要畫圖的座標。draw() 函式是依更新後的座標把圖畫出來。接下來的範例是一個左右移動的方塊,碰到右邊反回,碰到左邊再反回,如下圖: 完整的程式碼:
<script>
window.requestAnimFrame = (function(callback) {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 1000 / 60);
};
})();
window.onload = function() {
init();
loop();
};
var canvas, context;
var lastTime;
var x, y;
var rW, rH;
var speed;
//初始化
function init() {
canvas = document.getElementById("myCanvas");
context = canvas.getContext("2d");
x = 0;
y = 100;
rW = 100;
rH = 100;
speed = 100;
lastTime = new Date().getTime();
}
//時間迴圈
function loop() {
requestAnimFrame(loop);
update();
draw();
}
//執行繪圖
function draw() {
//清除整個畫布
context.clearRect(0, 0, canvas.width, canvas.height);
context.fillStyle = 'red';
context.beginPath();
context.fillRect(x, y, rW, rH);
context.closePath();
context.fill();
}
//計算
function update(){
var time = new Date().getTime();
var diff = time - lastTime;
var distFrame = speed * diff / 1000;
x = x + distFrame;
//碰到右邊往回
if (x > canvas.width - rW){
x = canvas.width - rW;
speed *= -1;
}
//碰到左邊往回
if (x < 0){
x = 0;
speed = Math.abs(speed);
}
lastTime = time;
}
</script>
我要留言
留言小提醒:
1.回覆時間通常在晚上,如果太忙可能要等幾天。
2.請先瀏覽一下其他人的留言,也許有人問過同樣的問題。
3.程式碼請先將它編碼後再貼上。(線上編碼:http://bit.ly/1DL6yog)
4.文字請加上標點符號及斷行,難以閱讀者恕難回覆。
5.感謝您的留言,您的問題也可能幫助到其他有相同問題的人。