requestAnimationFrame-制作逐幀動(dòng)畫

window.requestAnimationFrame() 方法告訴瀏覽器您希望執(zhí)行動(dòng)畫,并請(qǐng)求瀏覽器調(diào)用指定的函數(shù)在下一次重繪之前更新動(dòng)畫。該方法將在重繪之前調(diào)用的回調(diào)作為參數(shù)。如果你想做逐幀動(dòng)畫的時(shí)候,你應(yīng)該用這個(gè)方法。這就要求你的動(dòng)畫函數(shù)執(zhí)行會(huì)先于瀏覽器重繪動(dòng)作。通常來(lái)說(shuō),被調(diào)用的頻率是每秒60次,但是一般會(huì)遵循W3C標(biāo)準(zhǔn)規(guī)定的頻率。如果是后臺(tái)標(biāo)簽頁(yè)面,重繪頻率則會(huì)大大降低。

瀏覽器的顯示頻率一般是16.7ms,我們將setTimeout的間隔時(shí)間設(shè)為16.7ms,節(jié)奏會(huì)如下圖第一行展示 。但如果我們將間隔時(shí)間設(shè)為10ms,那么節(jié)奏會(huì)如下圖第二行展示。


frame-lost.png

舉個(gè)例子:

國(guó)慶北京高速,最多每16.7s通過(guò)一輛車,結(jié)果,突然插入一批setTimeout的軍車,強(qiáng)行要10s通過(guò)。顯然,這是超負(fù)荷的,要想順利進(jìn)行,只能讓第三輛車直接消失(正如顯示繪制第三幀的丟失)。然而,這是不現(xiàn)實(shí)的,于是就有了會(huì)堵車!

同樣的,顯示器16.7ms刷新間隔之前發(fā)生了其他繪制請(qǐng)求(setTimeout),導(dǎo)致所有第三幀丟失,繼而導(dǎo)致動(dòng)畫斷續(xù)顯示(堵車的感覺(jué)),這就是過(guò)度繪制帶來(lái)的問(wèn)題。不僅如此,這種計(jì)時(shí)器頻率的降低也會(huì)對(duì)電池使用壽命造成負(fù)面影響,并會(huì)降低其他應(yīng)用的性能。

這也是為何setTimeout的定時(shí)器值推薦最小使用16.7ms的原因(16.7 = 1000 / 60, 即每秒60幀)。

而requestAnimationFrame就是為了解決這個(gè)問(wèn)題而出現(xiàn)的。它所做的事情很簡(jiǎn)單,就是跟著瀏覽器的繪制走,如果瀏覽設(shè)備繪制間隔是16.7ms,那它就在這個(gè)間隔繪制。如果瀏覽設(shè)備繪制間隔是10ms,它就10ms繪制。這樣就不會(huì)存在過(guò)度繪制的問(wèn)題,動(dòng)畫不會(huì)掉幀,播放自然流暢。

兼容性

2017-04-02_112747.jpg

統(tǒng)一的向下兼容方法:

(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'] ||    // Webkit中此取消方法的名字變了
    window[vendors[x] + 'CancelRequestAnimationFrame'];
  }

  if (!window.requestAnimationFrame) {
    window.requestAnimationFrame = function(callback, element) {
      var currTime = new Date().getTime();
      var timeToCall = Math.max(0, 16.7 - (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);
    };
  }
}());

原文來(lái)自:http://www.zhangxinxu.com/wordpress/?p=3695

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 在iOS中隨處都可以看到絢麗的動(dòng)畫效果,實(shí)現(xiàn)這些動(dòng)畫的過(guò)程并不復(fù)雜,今天將帶大家一窺ios動(dòng)畫全貌。在這里你可以看...
    每天刷兩次牙閱讀 8,688評(píng)論 6 30
  • 在iOS中隨處都可以看到絢麗的動(dòng)畫效果,實(shí)現(xiàn)這些動(dòng)畫的過(guò)程并不復(fù)雜,今天將帶大家一窺iOS動(dòng)畫全貌。在這里你可以看...
    F麥子閱讀 5,261評(píng)論 5 13
  • 原文: http://www.cnblogs.com/yezhennan/p/5442031.html UI性能測(cè)...
    vb12閱讀 4,602評(píng)論 0 9
  • 作為一只前端狗,我們的使命就是在滿足產(chǎn)品需求、實(shí)現(xiàn)交互設(shè)計(jì)的基礎(chǔ)上,將最好的體驗(yàn)呈現(xiàn)給用戶爸爸們。在保證性能的同時(shí)...
    桂圓_noble閱讀 4,293評(píng)論 5 14
  • 當(dāng)我們要在頁(yè)面上實(shí)現(xiàn)一些動(dòng)畫效果的時(shí)候,通常會(huì)考慮兩種方式: 1、通過(guò)css3的animation+keyfram...
    點(diǎn)融黑幫閱讀 1,696評(píng)論 0 28

友情鏈接更多精彩內(nèi)容