requestAnimationFrame是什么?
在瀏覽器動畫程序中,我們通常使用一個定時器來循環每隔幾毫秒移動目標物體一次,來讓它動起來。如今有一個好消息,瀏覽器開發商們決定:“嗨,為什么我們不在瀏覽器里提供這樣一個API呢,這樣一來我們可以為用戶優化他們的動畫。”所以,這個requestAnimationFrame()函數就是針對動畫效果的API,你可以把它用在DOM上的風格變化或畫布動畫或WebGL中。
使用requestAnimationFrame有什么好處?
瀏覽器可以優化并行的動畫動作,更合理的重新排列動作序列,并把能夠合并的動作放在一個渲染周期內完成,從而呈現出更流暢的動畫效果。比如,通過requestAnimationFrame(),JS動畫能夠和CSS動畫/變換或SVG SMIL動畫同步發生。另外,如果在一個瀏覽器標簽頁里運行一個動畫,當這個標簽頁不可見時,瀏覽器會暫停它,這會減少CPU,內存的壓力,節省電池電量。
requestAnimationFrame的用法
// shim layer with setTimeout fallback
window.requestAnimFrame=(function(){
? return ? window.requestAnimationFrame||
? ? ? ? ? ? ?window.webkitRequestAnimationFrame||
? ? ? ? ? ? ?window.mozRequestAnimationFrame||
? ? ? ? ? ? function(callback){
? ? ? ? ? ? window.setTimeout(callback,1000/60);};
})();
// usage:
// instead of setInterval(render, 16) ....
(functionanimloop(){
? requestAnimFrame(animloop);
? render();
})();
// place the rAF *before* the render() to assure as close to ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 60fps with the setTimeout fallback.
對requestAnimationFrame更牢靠的封裝
Opera瀏覽器的技術師Erik M?ller把這個函數進行了封裝,使得它能更好的兼容各種瀏覽器。你可以讀一讀這篇文章,但基本上他的代碼就是判斷使用4ms還是16ms的延遲,來最佳匹配60fps。下面就是這段代碼,你可以使用它,但請注意,這段代碼里使用的是標準函數,我給它加上了兼容各種瀏覽器引擎前綴。
(function(){
var lastTime=0;
var vendors=['webkit','moz'];
for(varx=0;x<vendors.length;&&!window.requestAnimationFrame;++x){
window.requestAnimationFrame=window[vendors[x]+'RequestAnimationFrame'];
window.cancelAnimationFrame=window[vendors[x]+'CancelAnimationFrame']||window[vendors[x]+'CancelRequestAnimationFrame'];
}
if(!window.requestAnimationFrame)
window.requestAnimationFrame=function(callback,element){
var currTime=newDate().getTime();
var timeToCall=Math.max(0,16-(currTime-lastTime));
var id=window.setTimeout(function(){callback(currTime+timeToCall);},
timeToCall);
lastTime=currTime+timeToCall;
return id;
};
if(!window.cancelAnimationFrame)
window.cancelAnimationFrame=function(id){
clearTimeout(id);
};
}());
requestAnimationFrame API
window.requestAnimationFrame(function(/* time */time){ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?// time ~= +new Date // the unix time ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?});
回調函數里的參數可以傳入時間。
各種瀏覽器對requestAnimationFrame的支持情況
谷歌瀏覽器,火狐瀏覽器,IE10+都實現了這個函數,即使你的瀏覽器很古老,上面的對requestAnimationFrame封裝也能讓這個方法在IE8/9上不出錯。