## 基礎動畫
實現動畫,我們首先想到的肯定是`setTimeout`和`setInterval`,這兩個在這里就不細說了。
除了這兩個外,我們還可以使用`requestAnimationFrame()`這個方法。
`requestAnimationFrame` 是專門為實現高性能的幀動畫而設計的一個API
`requestAnimationFrame()`這個方法是用來在頁面重繪之前,通知瀏覽器調用一個指定的函數,以滿足開發者操作動畫的需求。這個方法接受一個函數為參,該函數會在重繪前調用。
注意: 如果想得到連貫的逐幀動畫,函數中必須重新調用 `requestAnimationFrame()`。
如果你想做逐幀動畫的時候,你應該用這個方法。這就要求你的動畫函數執行會先于瀏覽器重繪動作。通常來說,被調用的頻率是每秒60次,但是一般會遵循W3C標準規定的頻率。如果是后臺標簽頁面,重繪頻率則會大大降低。
回調函數只會被傳入一個DOMHighResTimeStamp參數,這個參數指示當前被 requestAnimationFrame 序列化的函數隊列被觸發的時間。因為很多個函數在這一幀被執行,所以每個函數都將被傳入一個相同的時間戳,盡管經過了之前很多的計算工作。這個數值是一個小數,單位毫秒,精確度在 10 μs。
參數 callback 在每次需要重新繪制動畫時,會調用這個參數所指定的函數。這個回調函數會收到一個參數,這個 DOMHighResTimeStamp 類型的參數指示當前時間距離開始觸發 `requestAnimationFrame` 的回調的時間。 返回值 requestID 是一個長整型非零值,作為一個唯一的標識符.你可以將該值作為參數傳給 `cancelAnimationFrame()` 來取消這個回調函數。
```
if (!window.requestAnimationFrame) {
window.requestAnimationFrame = (window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.msRequestAnimationFrame ||
window.oRequestAnimationFrame ||
function (callback) {
return window.setTimeout(callback, 1000 / 60 );
});
}
if (!window.cancelAnimationFrame) {
window.cancelAnimationFrame = (window.cancelRequestAnimationFrame ||
window.webkitCancelAnimationFrame || window.webkitCancelRequestAnimationFrame ||
window.mozCancelAnimationFrame || window.mozCancelRequestAnimationFrame ||
window.msCancelAnimationFrame || window.msCancelRequestAnimationFrame ||
window.oCancelAnimationFrame || window.oCancelRequestAnimationFrame ||
window.clearTimeout);
}
```
實例:canvas-demo/requestAnimationFrame.html:
```
<canvas id="canvas" width="600" height="400">
不支持canvas
</canvas>
<script>
var canvas = document.getElementById('canvas');
var ctx = '';
ctx = canvas.getContext('2d');
var dirt = 0;
var vx = 3;
gameStart();
function gameStart() {
ctx.clearRect(0, 0, 600, 400);
if (dirt + 50 >= canvas.width || dirt < 0) {
vx = -vx;
}
dirt = dirt + vx;
ctx.fillRect(dirt, 0, 50, 50);
requestAnimationFrame(gameStart);
}
</script>
```