js利用H5的requestAnimationFrame()API實現動畫效果

newbeehh發表於2018-06-20

為什麼要使用requestAnimationFrame:

    • 我們知道,瀏覽器實現動畫繪製無非就是CSS3的動畫屬性transitionaniamtion和JavaScript的setTImeOutsetInterval方法(進行DOM的樣式迴圈改變達到動畫效果)。說到這可能很多同學都有疑問了,既然有CSS的動畫屬性這麼方便的東西了,為何還要用setTimeOut等js方法這麼麻煩呢?我們首先來解決這個疑問。

      •  CSS3的動畫屬性與JavaScript的動畫方法:

        1. 一個事物的存在必有其存在的道理,api也不例外,不然早被淘汰了。首先CSS3的動畫屬性是存在相容問題的,最明顯的就是IE10之後才相容。而目前主流的向下相容的標準還是要達到IE9的,所以setTImeOut等js方法還是主流的動畫解決方案。
        2. 有些動畫效果CSS3無法實現,如改變元素scrollTop的值進行滾動,這樣就只能使用js的相關方法了。
        3. CSS3的動畫無法實現過於複雜的動畫效果,如CSS3支援控制動畫速度賽貝爾曲線的數值有限,更復雜的動畫效果得使用js結合相關演算法才能完成
    • 接著回到正題哈, 那requestAnimationFramesetTimeOutsetInterval又有和區別呢,嗯,接下來就是正題了。
      • setTimeOutsetInterval出現的問題:

        1. 首先,我們得知道動畫的渲染是一幀一幀的進行的,每一幀就是動畫的一個靜止狀態,每一幀連起來就成為了一個動畫。因此每一幀的時間間隔要足夠短動畫才顯得平滑流暢,但每一幀又不能間隔得太短,因為瀏覽器每一秒的渲染能是有限的,而且螢幕的重新整理能力也是有限的,大多數的顯示器重新整理頻率是60H也就是每秒60幀,因此瀏覽器的重繪頻率不會超過顯示器的重新整理頻率。
        2. 所以每一幀大約17秒就是最佳的重繪間隔。那使用就直接使用setTimeOut或者setInterval,間隔設定為17不就得了?但這樣還是不行的。
          1. 因瀏覽器的毫秒不精確:瀏覽器的計時器精度並非精確到毫秒級的,IE8的精確度是15ms多一點,而IE9等大多數的瀏覽器精確度都在4ms差不多。所以難以保證動畫最佳的時間間隔。
          2. 不同的瀏覽器渲染能力不同,因此並非每一幀17ms就是最佳渲染間隔。
          3. 在不需要動畫的地方,如後臺標籤頁,動畫任然在執行,消耗CPU的效能。
    • 因此,h5的requestAnimationFrame就是解決以上問題的。

      • requestAnimationFrame的特點:

      1. requestAnimationFrame會把每一幀中所有的DOM操作集中起來,在一次重繪或者重排中就完成。
      2. requestAnimationFrame重繪或者重排的時間間隔是系統的時間間隔,因為不同的瀏覽器的系統時間間隔不同,requestAnimationFrame將會保持最佳的繪製間隔,即不會因為繪製間隔時間過短而造成瀏覽器渲染能力跟不上,也不會因為繪製間隔時間過長,而造成動畫卡頓。這樣就能在不同的瀏覽器中實現最佳的繪製效果。
      3. 在隱藏或者不可見的元素中,requestAnimationFrame將不會進行重排或者重繪,而執行在頁面沒有啟用的情況下,如requestAnimationFrame執行在後臺標籤頁中,動畫將會暫停,有效的節省了CPU的開銷。
        • 那麼,該如何使用requestAnimationFrame呢?

      requestAnimationFrame的具體使用:

        • requestAnimationFrame使用非常簡單,只需傳入改變DOM的函式,然後反覆呼叫requestAnimationFrame即可達到動畫效果了。requestAnimationFrame返回一個整數型請求id的,可以用cancelAnimationFrame函式去取消傳入requestAnimationFrame的回撥函式。具體使用可以看MDN的教程

      後話:


      相關文章