參考文檔:http://www.zyiz.net/tech/detail-16035.html
編寫動畫循環時,關鍵是要知道循環的延遲時間多長合適,即GPU處理生成 每張圖片的速度是否和瀏覽器屏幕刷新頻率一致。
如果GPU處理生成每張圖片的速度 < 屏幕刷新頻率,就會出現多次刷新時顯示同一張圖片的現象,即用戶會感覺動畫出現卡頓;
如果GPU處理生成每張圖片的速度 > 屏幕刷新頻率,就會出現有些圖片沒有被展示出來,也就是我們說的丟幀現象。
大多數顯示器的刷新頻率是60Hz,相當于每秒鐘重繪60次。
setInterval 定時器
是在特定的時間間隔去執行任務,時間間隔需要自己設定,為了平滑的顯示動畫,我們一般設置延遲時間是為1000/60;
但是因為setInterval是宏任務,需要等同步任務、微任務執行完成才會執行,如果同步任務、微任務的任務執行時間較長超過定時器得設定時間,那setInterval最終執行時間是大于設置時間,用戶就會感覺動畫出現卡頓。
var e = document.getElementById("e");
let left = 0;
let toRight = true
function render() {
if(toRight) {
if(left >= 100) {
toRight = false;
}
left++;
}else{
if(left <= 0) {
toRight = true;
}
left--;
}
e.style.left = `${left}px`;
}
setInterval(render, 1000/60);
requestAnimationFrame
原生的API去執行動畫的效果,回調函數執行次數通常與瀏覽器屏幕刷新次數相匹配,一般是16ms/每次,即60ms/幀
執行時機: 下次重繪前執行
當
requestAnimationFrame()
運行在后臺標簽頁或者隱藏的<iframe>
里時,會被暫停調用以提升性能和電池壽命。
var e = document.getElementById("e");
let left = 0;
let toRight = true
function render2() {
if(toRight) {
if(left >= 100) {
toRight = false;
}
left++;
}else{
if(left <= 0) {
toRight = true;
}
left--;
}
e.style.left = `${left}px`;
}
(function loop() {
render2();
requestAnimationFrame(loop)
})()
requestAnimationFrame與setInterval的區別?
setInterval動畫延遲時間需要手動設置,且執行時間不穩定,無法保證按時繪制每一幀圖片
requestAnimationFrame不需要指定幀速率,瀏覽器內部會自行計算每一幀的執行時間
-- 當顯屏幕示器將一幀畫面繪制完成后,在準備讀取下一幀之前,顯示器會發出一個垂直同步信號(vertical synchronization)給 GPU,GPU收到信號后開始生成新的圖片
-- 即requestAnimationFrame的回調任務會在每一幀的開始時執行