一般我們繪畫動畫會使用計時器罪佳,動畫的形成本身就是一幀一幀的畫面按照一定的速度展示出來政敢,使用計時器就是為了把渲染出來的圖像按照我們能感知到的速度展示出來挽牢,例如一個旋轉(zhuǎn)動畫摆舟,需要把旋轉(zhuǎn)圖片拆分成幾個旋轉(zhuǎn)90°的動作,使用計時器一步一步旋轉(zhuǎn)以達到用戶能看到的旋轉(zhuǎn)效果噪服。
但是這里就會出現(xiàn)一些問題毡泻,每臺設(shè)備的渲染幀頻率不會完全相同,動畫渲染不一粘优,可能出現(xiàn)不流暢的情況牙捉,如果是一些性能較差的低配手機,甚至?xí)那闆r敬飒。
setTimeout
一般動畫編寫我們會使用setTimeout這個函數(shù),但是利用seTimeout實現(xiàn)的動畫在一些低端機上會出現(xiàn)失幀芬位、卡頓无拗、抖動等現(xiàn)象。 產(chǎn)生有兩個原因:
setTimeout的執(zhí)行時間并不是確定的昧碉。在Javascript中英染, setTimeout 任務(wù)被放進了異步隊列中,只有當(dāng)主線程上的任務(wù)執(zhí)行完以后被饿,才會去檢查該隊列里的任務(wù)是否需要開始執(zhí)行四康,因此 setTimeout 的實際執(zhí)行時間一般要比其設(shè)定的時間晚一些。
上面我們提到的一點:每臺設(shè)備的渲染幀頻率不會完全相同狭握,動畫渲染不一闪金,刷新頻率又受屏幕分辨率和屏幕尺寸的影響,setTimeout只能設(shè)置一個固定的時間間隔,這個時間不一定和屏幕的刷新時間吻合哎垦。
setTimeout執(zhí)行的圖像變化并不是馬上反應(yīng)到屏幕囱嫩,這個變化必須要等到屏幕下次刷新時才會被更新到屏幕上。如果我們定義的時間和屏幕的刷新時間步調(diào)不一致漏设,就可能會導(dǎo)致中間某一幀的操作被跨越過去墨闲,而直接更新下一幀的圖像,從而導(dǎo)致失幀郑口。
requestAnimationFrame
requestAnimationFrame是html5提供的的一個叫請求動畫幀的api鸳碧。這個api是根據(jù)系統(tǒng)渲染屏幕時間來調(diào)用的,每渲染一次就調(diào)用一次犬性,這樣就保證了幀數(shù)完整地執(zhí)行并且不會失幀瞻离。
function animate() {
left ++
console.log("animation");
if (left <50) {
window.requestAnimationFrame(animate);
}
}
//第一幀渲染
window.requestAnimationFrame(animate);
兼容:
var requestAnimationFrame = window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(callback){window.setTimeout(callback,1000/60);};