動(dòng)畫認(rèn)識(shí)及requestAnimationFrame

業(yè)界動(dòng)畫引擎


PhysicsJS: 基于JavaScript仍劈、模塊化娄猫、可擴(kuò)展、易于使用的物理引擎外冀,github
animate.css: CSS3動(dòng)畫寡键,github
Matter.js: 基于canvas,兼容IE9+雪隧,github
collie:基于Canvas西轩,IE9+

FPS


動(dòng)畫間隔決定了動(dòng)畫的每秒幀數(shù)(FPS), 一般來說,F(xiàn)PS越高脑沿,也就是每秒播放的幀數(shù)越多藕畔,動(dòng)畫會(huì)越流暢,但是庄拇,因?yàn)榇蟛糠值娘@示器刷新頻率是 60Hz注服,當(dāng)動(dòng)畫的FPS超過 60Hz 時(shí),顯示器會(huì)把兩個(gè)或更多的幀顯示在同一畫面上措近,這樣就會(huì)出現(xiàn) 畫面撕裂溶弟,畫面撕裂跟掉幀一個(gè)意思,所以通常來講 FPS 為 60frame/s 時(shí)動(dòng)畫效果最好熄诡,也就是每幀16.67ms可很,在瀏覽器中要減去渲染時(shí)間1ms左右,得到的結(jié)果是每幀時(shí)間大概15ms凰浮。但是我們可以在 jQuery 的源碼中發(fā)現(xiàn)它的 interval是13ms:jQuery.fx.interval = 13我抠, 按照上面的說法:1000 /(13+1.5)= 70 > 60hz苇本,這樣會(huì)出現(xiàn)畫面撕裂,作為業(yè)界標(biāo)準(zhǔn)的 jQuery 顯然是不會(huì)出現(xiàn)這種低級(jí)錯(cuò)誤的菜拓,所以2ms的差別是怎么個(gè)意思瓣窄?John Resig有一篇博客對(duì)13ms做了解釋,文章鏈接見末尾纳鼎。因?yàn)閖Query的動(dòng)畫是基于 setInterval
的俺夕,所以會(huì)存在一定的延遲:setTimeout(func, delay),這里是說在delay時(shí)間后將任務(wù) func加入 UI 任務(wù)隊(duì)列贱鄙,而非立即執(zhí)行該任務(wù)劝贸,所以這里會(huì)有一定的延遲;各瀏覽器定時(shí)器精度的差異逗宁。

對(duì)于 setInterval的問題映九,新的方法 requestAnimationFrame
是很好的改進(jìn),具體可參見The secret to silky smooth JavaScript animation!這篇文章瞎颗。

參考:
stackoverflow
jQuery 的動(dòng)畫幀寬為什么是 13ms 呢
使用requestAnimationFrame更好的實(shí)現(xiàn)javascript動(dòng)畫

requestAnimationFrame:


setInterval和 setTimeout的缺陷*
無論是setInterval()還是setTimeout()都無法達(dá)到精確件甥,這個(gè)延遲即你指定的第二個(gè)參數(shù)僅僅表示何時(shí)代碼會(huì)添加到瀏覽器的可能被執(zhí)行的UI線程隊(duì)列中。如果隊(duì)列中有其他工作在此之前哼拔,那代碼將會(huì)等到他完成才會(huì)執(zhí)行引有。簡(jiǎn)而言之倦逐,毫秒級(jí)的延遲不是表示何時(shí)代碼會(huì)執(zhí)行,而是表示何時(shí)代碼會(huì)添加進(jìn)隊(duì)列檬姥;

當(dāng)相應(yīng)的瀏覽器窗口最小化,JavaScript 計(jì)時(shí)器在背景標(biāo)簽仍然持續(xù)運(yùn)行穿铆,消耗CPU和電池。

CSS transitions和 animations
優(yōu)勢(shì)在于瀏覽器知道哪些動(dòng)畫將會(huì)發(fā)生斋荞,所以得到正確的間隔來刷新UI荞雏。而javascript動(dòng)畫,瀏覽器不知道動(dòng)畫正在發(fā)生平酿,所以催生了requestAnimationFrame凤优,對(duì)于延遲做了很大程度的優(yōu)化。

僅繪制用戶可見的動(dòng)畫蜈彼,這意味著在頁面不可見時(shí)不會(huì)繪制動(dòng)畫筑辨,節(jié)省 CPU 和電池;繪制動(dòng)畫不可能出現(xiàn)多個(gè)排隊(duì)的回調(diào)函數(shù)幸逆,或者阻塞瀏覽器;由于瀏覽器準(zhǔn)備好時(shí)(空閑時(shí))才繪制幀棍辕,不會(huì)有等待繪制的幀暮现,沒有多余的幀繪制,因此動(dòng)畫更平滑楚昭,CPU 和電池使用被進(jìn)一步優(yōu)化栖袋。

注意:在有多個(gè)動(dòng)畫時(shí),出現(xiàn)一個(gè)可見一個(gè)不可見抚太,requestAnimationFrame 會(huì)導(dǎo)致動(dòng)畫不同步塘幅,所以, 指定一個(gè)參數(shù)確保所有需要同步的動(dòng)畫狀態(tài)尿贫,不受可見程度的影響(如一組動(dòng)畫從開始以來經(jīng)過的時(shí)間)电媳,而不是根據(jù)每個(gè)動(dòng)畫的前一幀。

兼容各瀏覽器的requestAnimationFrame

 (function() {
    var lastTime = 0;
    var vendors = ['webkit', 'moz' /*, 'ms', 'o'*/];
    for(var x = 0,len = vendors.length ; x < len && !window.requestAnimationFrame; ++x) {
    window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame'];
    window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame'] ||    // name has changed in 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);
       };
    }
}());



/* 方案2:*/

var oldStyleMove = (function() {
var timeLast = 0
return function( callback ) {
    var timeCurrent = +new Date(),
        timeDelta

    timeDelta = Math.max( 0, 16 - ( timeCurrent - timeLast ))
    timeLast  = timeCurrent + timeDelta

    return setTimeout( function() { 
        callback( timeCurrent + timeDelta ) 
    }, timeDelta )
   }
})(),

WIN = window,

requestAnimationFrame = WIN.requestAnimationFrame       ||
                    WIN.webkitRequestAnimationFrame ||
                    WIN.mozRequestAnimationFrame    ||
                    oldStyleMove,

cancelAnimationFrame  = WIN.cancelAnimationFrame       ||
                    WIN.webkitCancelAnimationFrame ||
                    WIN.mozCancelAnimationFrame    ||
                    function( timeoutID ) {
                        clearTimeout( timeoutID )
                    };

Web動(dòng)畫性能指南

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末庆亡,一起剝皮案震驚了整個(gè)濱河市匾乓,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌身冀,老刑警劉巖钝尸,帶你破解...
    沈念sama閱讀 206,839評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異搂根,居然都是意外死亡珍促,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門剩愧,熙熙樓的掌柜王于貴愁眉苦臉地迎上來猪叙,“玉大人,你說我怎么就攤上這事仁卷⊙妫” “怎么了?”我有些...
    開封第一講書人閱讀 153,116評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵锦积,是天一觀的道長(zhǎng)芒帕。 經(jīng)常有香客問我,道長(zhǎng)丰介,這世上最難降的妖魔是什么背蟆? 我笑而不...
    開封第一講書人閱讀 55,371評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮哮幢,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘橙垢。我一直安慰自己,他們只是感情好嗽元,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,384評(píng)論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著还棱,像睡著了一般。 火紅的嫁衣襯著肌膚如雪办铡。 梳的紋絲不亂的頭發(fā)上琳要,一...
    開封第一講書人閱讀 49,111評(píng)論 1 285
  • 那天稚补,我揣著相機(jī)與錄音,去河邊找鬼课幕。 笑死,一個(gè)胖子當(dāng)著我的面吹牛杜秸,可吹牛的內(nèi)容都是我干的润绎。 我是一名探鬼主播,決...
    沈念sama閱讀 38,416評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼呢蛤,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼其障!你這毒婦竟也來了涂佃?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,053評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎侨拦,沒想到半個(gè)月后辐宾,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體膨蛮,經(jīng)...
    沈念sama閱讀 43,558評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡敞葛,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,007評(píng)論 2 325
  • 正文 我和宋清朗相戀三年惹谐,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了氨肌。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片酌畜。...
    茶點(diǎn)故事閱讀 38,117評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖恳守,靈堂內(nèi)的尸體忽然破棺而出贩虾,到底是詐尸還是另有隱情,我是刑警寧澤颗圣,帶...
    沈念sama閱讀 33,756評(píng)論 4 324
  • 正文 年R本政府宣布屁使,位于F島的核電站,受9級(jí)特大地震影響蔽午,放射性物質(zhì)發(fā)生泄漏及老。R本人自食惡果不足惜范抓,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,324評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望僧鲁。 院中可真熱鬧,春花似錦斟叼、人聲如沸春寿。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽萤悴。三九已至,卻和暖如春覆履,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背硝全。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評(píng)論 1 262
  • 我被黑心中介騙來泰國打工伟众, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人凳厢。 一個(gè)月前我還...
    沈念sama閱讀 45,578評(píng)論 2 355
  • 正文 我出身青樓先紫,卻偏偏與公主長(zhǎng)得像遮精,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子本冲,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,877評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • 動(dòng)畫檬洞,顧名思義疮胖,就是能“動(dòng)”的畫环戈。人的眼睛對(duì)圖像有短暫的記憶效應(yīng),所以當(dāng)眼睛看到多張圖片連續(xù)快速的切換時(shí)遮晚,就會(huì)被認(rèn)...
    彬_仔閱讀 1,620評(píng)論 1 8
  • 前言 本文主要參考w3c資料糜颠,從底層實(shí)現(xiàn)原理的角度介紹了requestAnimationFrame、cancelA...
    Bruce_zhuan閱讀 1,519評(píng)論 0 3
  • 一:在制作一個(gè)Web應(yīng)用或Web站點(diǎn)的過程中其兴,你是如何考慮他的UI元旬、安全性匀归、高性能耗帕、SEO、可維護(hù)性以及技術(shù)因素的...
    Arno_z閱讀 1,138評(píng)論 0 1
  • 看了很多視頻体啰、文章嗽仪,最后卻通通忘記了,別人的知識(shí)依舊是別人的钦幔,自己卻什么都沒獲得。此系列文章旨在加深自己的印象搀擂,因...
    DCbryant閱讀 716評(píng)論 0 2
  • 收獲: 什么是新聞?(新聞是新進(jìn)事實(shí)的報(bào)道哨颂,廣播電臺(tái)發(fā)布的新聞通過播音員的有聲語言傳達(dá)出來的播音創(chuàng)作就稱為新聞播音...
    毛毛i閱讀 85評(píng)論 0 0