使用js(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。如果不支持,則自行模擬部署該方法。

window.requestAnimFrame = (function(){
      return  window.requestAnimationFrame       || 
              window.webkitRequestAnimationFrame || 
              window.mozRequestAnimationFrame    || 
              window.oRequestAnimationFrame      || 
              window.msRequestAnimationFrame     || 
              function( callback ){
              /*按照1秒鐘60次(大約每16.7毫秒一次),來模擬requestAnimationFrame。*/
                window.setTimeout(callback, 1000 / 60);
              };
    })();

使用requestAnimationFrame的時候,只需反覆調用它即可。

(function repeatOften() {
	 console.log('持續輸出')
     requestAnimationFrame(repeatOften);
})()

cancelAnimationFrame方法用於取消重繪

window.cancelAnimationFrame(requestID);
//它的參數是requestAnimationFrame返回的一個代表任務ID的整數值。
//持續在body元素下添加div元素,直到用戶點擊stop按鈕爲止。
var globalID;
function repeatOften() {
	var div = document.createElement("div"); 
	div.innerHTML = '創建div'; 
	document.body.appendChild(div);
	globalID = requestAnimationFrame(repeatOften);
}
document.getElementById('start').addEventListener('click',function(){
	globalID = requestAnimationFrame(repeatOften);
})
document.getElementById('stop').addEventListener('click',function(){
	cancelAnimationFrame(globalID);
}) 

實例

<div id="anim">點擊運行動畫</div> 
var elem = document.getElementById("anim");
var startTime = undefined;
 let margin = 0;
 let isContinue = true;
function render() {
 margin===200?isContinue=false:margin===0?isContinue=true:false;
  isContinue?elem.style.left = `${margin++}px`:elem.style.left = `${margin--}px`;
}
elem.addEventListener('click',function animloop(){
  render();
  requestAnimFrame(animloop);
})
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章