天天看點

requestAnimationFrame

 requestAnimationFrame 是浏覽器用于定時循環操作的一個接口,類似于 setTimeout ,主要用途是按幀對網頁進行重繪。

設定這個API的目的是為了讓各種網頁動畫效果(DOM動畫、Canvas動畫、SVG動畫、WebGL動畫)能夠有一個統一的重新整理機制,進而節省系統資源,提高系統性能,改善視覺效果。代碼中使用這個API,就是告訴浏覽器希望執行一個動畫,讓浏覽器在下一個動畫幀安排一次網頁重繪。

 requestAnimationFrame 的優勢,在于充分利用顯示器的重新整理機制,比較節省系統資源。顯示器有固定的重新整理頻率(60Hz或75Hz),也就是說,每秒最多隻能重繪60次或75次, requestAnimationFrame 的基本思想就是與這個重新整理頻率保持同步,利用這個重新整理頻率進行頁面重繪。此外,使用這個API,一旦頁面不處于浏覽器的目前标簽,就會自動停止重新整理。這就節省了CPU、GPU和電力。

不過有一點需要注意, requestAnimationFrame 是在主線程上完成。這意味着,如果主線程非常繁忙, requestAnimationFrame 的動畫效果會大打折扣。

 requestAnimationFrame 使用一個回調函數作為參數。這個回調函數會在浏覽器重繪之前調用。

requestID = window.requestAnimationFrame(callback);       

目前,主要浏覽器Firefox 23 / IE 10 / Chrome / Safari)都支援這個方法。可以用下面的方法,檢查浏覽器是否支援這個API。如果不支援,則自行模拟部署該方法。

1  window.requestAnimFrame = (function(){
 2       return  window.requestAnimationFrame       || 
 3               window.webkitRequestAnimationFrame || 
 4               window.mozRequestAnimationFrame    || 
 5               window.oRequestAnimationFrame      || 
 6               window.msRequestAnimationFrame     || 
 7               function( callback ){
 8                 window.setTimeout(callback, 1000 / 60);
 9               };
10  })();      

上面的代碼按照1秒鐘60次(大約每16.7毫秒一次),來模拟 requestAnimationFrame 。

使用 requestAnimationFrame 的時候,隻需反複調用它即可。

1 function repeatOften() {
2   // Do whatever
3   requestAnimationFrame(repeatOften);
4 }
5 
6 requestAnimationFrame(repeatOften);      

cancelAnimationFrame方法

 cancelAnimationFrame 方法用于取消重繪。

window.cancelAnimationFrame(requestID);      

它的參數是requestAnimationFrame傳回的一個代表任務ID的整數值。

1 var globalID;
 2 
 3 function repeatOften() {
 4   $("<div />").appendTo("body");
 5   globalID = requestAnimationFrame(repeatOften);
 6 }
 7 
 8 $("#start").on("click", function() {
 9   globalID = requestAnimationFrame(repeatOften);
10 });
11 
12 $("#stop").on("click", function() {
13   cancelAnimationFrame(globalID);
14 });      

上面代碼持續在body元素下添加div元素,直到使用者點選stop按鈕為止。

執行個體

下面,舉一個執行個體。

假定網頁中有一個動畫區塊。

<div id="anim">點選運作動畫</div>      

然後,定義動畫效果。

1 var elem = document.getElementById("anim");
 2 
 3 var startTime = undefined;
 4  
 5 function render(time) {
 6  
 7   if (time === undefined)
 8     time = Date.now();
 9   if (startTime === undefined)
10     startTime = time;
11  
12   elem.style.left = ((time - startTime)/10 % 500) + "px";
13 }      

最後,定義click事件。

1 elem.onclick = function() {
2 
3     (function animloop(){
4       render();
5       requestAnimFrame(animloop);
6     })();
7 
8 };      

原文位址:https://javascript.ruanyifeng.com/htmlapi/requestanimationframe.html