一直以來都以為要用 setTimeout 或 setInterval 來製作動畫,但 setTimeout 最快也只能到 10 毫秒,可能造成畫面遺失的問題,而我們就可以用 requestAnimationFrame 這個方法。 一起來看一下 MicroSoft Developer Network 提供的這個例子,在裡面學到不少東西。
支援度
說明:
window.performance.now 高精準的時間戳,可以取到一毫秒的千分之一
elm.style.left = ((lpos += 3) % 600) + "px"; 利用累加方式調整矩形位置,並用餘數值來限定範圍
requestId = window.requestAFrame(render) 計算 requestAFrame 執行的次數, requestAFrame 的回傳值會從 1 開始持續往上累加
<body onload="init();">
<div id="animated">Hello there.</div>
<button onclick="start()">Start</button>
<button onclick="stop()">Stop</button>
</body>
div {
position: absolute;
left: 10px;
top:100px;
padding: 50px;
background: crimson;
color: white;
}
//多瀏覽器的支援
window.cancelAFrame = (function () {
return window.cancelAnimationFrame ||
window.webkitCancelAnimationFrame ||
window.mozCancelAnimationFrame ||
window.oCancelAnimationFrame ||
function (id) {
window.clearTimeout(id);
};
})();
var requestId = 0;
var startime = 0;
var lpos = 0;
var elm;
function init() {
elm = document.getElementById("animated");
}
function render() {
elm.style.left = ((lpos += 3) % 600) + "px";
requestId = window.requestAFrame(render);
}
function start() {
if (window.performance.now) {
startime = window.performance.now();
} else {
startime = Date.now();
}
requestId = window.requestAFrame(render);
}
function stop() {
if (requestId)
window.cancelAFrame(requestId);
}
// handle multiple browsers for requestAnimationFrame()
window.requestAFrame = (function () {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
// if all else fails, use setTimeout
function (callback) {
return window.setTimeout(callback, 1000 / 60); // shoot for 60 fps
};
})();
// handle multiple browsers for cancelAnimationFrame()
參考資料:指令碼式動畫的計時控制項