requestAnimationFrame()用法

admin發表於2017-04-15

在此之前,我們要在頁面實現動畫有以下幾種方式:

(1).使用css3的相關屬性。

(2).使用canvas。

(3).使用setTimout()或者setInterval()。

使用setTimout()或者setInterval()這兩個定時器函式實現動畫是最為原始簡單的方式,但是缺點也很大。

最重要的一個缺點就是有可能出現丟幀現象;現在大部分瀏覽器的重新整理頻率是16.7ms,當你當定時器函式的時間間隔小於這個值,比如是10ms就會發生丟幀;下面粗略描繪一下這個過程:

(1).當第一個繪製請求到來,並繪製完成,瀏覽器重新整理一次,完全沒有問題,頁面上顯示此次繪製的效果。

(2).10ms以後第二個繪製請求到來,並繪製完成,那麼需要等待6.7ms才能顯示此次繪製效果。

(3).第二次繪製完成之後3.3ms,第三次請求繪製到來,這時候距離第三次瀏覽器重新整理還需要13.4ms,當第四次繪製請求到來,第三次重新整理還沒有到來;那麼當三次重新整理到來的時候,第三次繪製請求的效果就會被第四次的效果所覆蓋,這也就是所謂的丟幀。

requestAnimationFrame()方法從名稱看 ,就是專門設計用來完成動畫的,並且它是跟隨瀏覽器的重新整理頻率,如果瀏覽器的重新整理頻率是16.7ms,那麼它就間隔16.7ms繪製,如果重新整理頻率是10ms,那麼就間隔10ms繪製。

主要優點如下:

(1).requestAnimationFrame會把每一幀中的所有DOM操作集中起來,在一次重繪或迴流中就完成,並且重繪或迴流的時間間隔緊緊跟隨瀏覽器的重新整理頻率,一般來說,這個頻率為每秒60幀

(2).隱藏或不可見的元素或者非當前啟用選項卡頁面,requestAnimationFrame將不會進行重繪或迴流,這當然就意味著更少的的cpu,gpu和記憶體使用量。在老版本的瀏覽器中,setTimeout()或者setInterval()在非啟用的選項卡頁面中也會照常執行,據說在當前的谷歌和火狐瀏覽器中,這兩個方法得到了優化,具有和

requestAnimationFrame()類似的行為,當頁面處於閒置狀態的時候,如果定時間隔小於1000ms,則停止了定時器的執行,不過時間間隔大於或等於1000ms,定時器依然執行,即使頁面最小化或非啟用狀態。

程式碼例項如下:

[HTML] 純文字檢視 複製程式碼
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="author" content="http://www.softwhy.com/" />
<title>螞蟻部落</title>
<style>
#antzone {
  width:1px;
  height:17px;
  background:#0f0;
}
</style>
<script>
window.onload=function(){
  window.requestAnimationFrame = window.requestAnimationFrame ||
                                 window.mozRequestAnimationFrame ||
                                 window.webkitRequestAnimationFrame ||
                                 window.msRequestAnimationFrame;
  var start = null;
  var ele = document.getElementById("antzone");
  var progress = 0;
 
  function step() {
    progress += 1;
    ele.style.width = progress + "%";
    ele.innerHTML = progress + "%";
    if (progress < 100) {
      requestAnimationFrame(step);
    }
  }
  requestAnimationFrame(step);
  document.getElementById("run").addEventListener("click", function () {
    ele.style.width = "1px";
    progress = 0;
    requestAnimationFrame(step);
  }, false);
}
</script>
</head>
<body>
  <div id="antzone">0%</div>
  <input type="button" value="檢視演示" id="run" />
</body>
</html>

和setInterval()類似,返回值也是一個標識,使用cancelAnimationFrame()可以停止動畫的執行。

相關文章