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