你可能用過定時器實現動畫(經過每隔一段時間去改變元素)。瀏覽器給咱們帶來了個好消息「爲何不提供一個API給開發者,來使一些事情更高效呢」。requestAnimationFrame就是爲動畫而生的API,用於改變dom樣式、canvas或WebGL。javascript
瀏覽器可以將並發動畫優化爲單個事件流和重繪週期中,從而更流暢。例如同時進行的以下任務:基於js的動畫、css動畫、SVG SMIL。並且,當正在執行動畫的標籤頁不可見時,瀏覽器並不會一直運行它,這就意味着更少的CPU、 GPU和內存的使用,從而延長電池壽命。css
是的大兄弟Totes McGoats(此人跟做者是啥關係~)java
下面這段是一個簡單的requestAnimationFrame兼容寫法,當瀏覽器不支持時回退到setTimeout的實現方式:web
// 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) .... (function animloop(){ requestAnimFrame(animloop); render(); })(); // place the rAF *before* the render() to assure as close to // 60fps with the setTimeout fallback.
如下代碼是Opera工程師Erik Möller所寫更加健壯的polyfill。你能夠閱讀下,尤爲是在處理4-16ms的延遲時間這段代碼,從而使幀率更接近60fps。你會喜歡上它的,請注意他使用的標準方法名。我同時也修正了cancel方法名稱(WebKit內核的瀏覽器已更改過)。canvas
(function() { var lastTime = 0; var vendors = ['webkit', 'moz']; for(var x = 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 = new Date().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); }; }());
http://jsfiddle.net/XQpzU/435...瀏覽器
window.requestAnimationFrame(function(/* time */ time){ // time ~= +new Date // the unix time });
該回調函數將當前時間做爲參數傳遞,也正是你說須要的。併發
(此文寫於2011年,下面介紹了不一樣瀏覽器實現上的差別)
Is it ready?
Right now, the Webkit implementation (available in Nightly Safari and Chrome Dev Channel) and the Mozilla one (available in FF4) differ slightly. Mozilla’s has a bug which caps potential framerates at about 30fps.Actually, 「It’s currently capped at 1000/(16 + N) fps, where N is the number of ms it takes your callback to execute. If your callback takes 1000ms to execute, then it’s capped at under 1fps. If your callback takes 1ms to execute, you get about 60fps.」 (thx, Boris) It’ll be fixed though, probably for the next release after FF4 ships. Also Chrome 10 doesn’t have the time parameter (added in m11), FF currently ignores the element argument.app