背景
過年的項目中碰到一個題目讓我百思不得其解,顯著我的幀率保持在60幀,為什麼我的動畫卻一向發抖?
我的場景是一個勻速直線運動的小姐姐。
先上一個 Demo
在這個 Demo 中,小姐姐是根據 x 軸 10px/s,y 軸 30 px/s 舉行挪動的,不過她的挪動是顯著伴隨着發抖的。
這究竟是怎麼了呢?
處理
假如小姐姐的y軸速率是 10px/s,我們的幀率是 60f/s,盤算一下:
10 / 60 = 1/6 (px/f)
現實上,的現實速率是每 6 幀才會挪動 1px,這固然會有發抖,小姐姐走一步停一會,總覺得怪怪的~
我乾脆把小姐姐的挪動速率調快,調成 100px/s,發明,照樣會發抖,認為高高興興能處理了這個題目,發明照樣沒那末簡樸。
既然我們能算,那我們就算一算
100 / 60 = 10/6 (px/f) = 1.666666....(px/f)
寫了個for輪迴,看看一秒中每一幀小姐姐都在什麼位置
for(let i = 0; i < 60; i ++) {
console.log(i*10/6)
}
輸出效果取小數點后兩位是如許的:
0.00 1.67 3.33 5.00 6.67 8.33 10.00 11.67 13.33 15.00 16.67 18.33 20.00 21.67 23.33 25.00 26.67 28.33 30.00 31.67
33.33 35.00 36.67 38.33 40.00 41.67 43.33 45.00 46.67 48.33 50.00 51.67 53.33 55.00 56.67 58.33 60.00 61.67 63.33
65.00 66.67 68.33 70.00 71.67 73.33 75.00 76.67 78.33 80.00 81.67 83.33 85.00 86.67 88.33 90.00 91.67 93.33 95.00 96.67 98.33
那末作為浮點數,Canvas 將怎樣定位呢?
我們來寫一個 Demo
運用 Chrome 翻開,作為一個像素眼,我發明,小姐姐定位在 50.6px 的時刻,實在就已被襯着到 51px 的位置。
所以在 Chrome 中,drawImage
中設置的位置終究會被四舍五入,這能夠和 CSS Sub-pixel 有關 這裏先不探討。
所以真正的位置現實上是
0 2 3 5 7 8 10 12 13 15 17 18 20 22 23 25 27 28 30 32
33 35 37 38 40 42 43 45 47 48 50 52 53 55 57 58 60 62 63 65
67 68 70 72 73 75 77 78 80 82 83 85 87 88 90 92 93 95 97 98
從數值來看,每幀挪動的間隔多是 1px 也多是 2px,小姐姐多是在邊跳芭蕾邊走路嘍~
既然如許,60 幀的幀率下,設置 60px/s 就能夠處理題目了,嘗試了一下,真的能夠!
總結
前端動畫/遊戲開闢 requestAnimationFrame 之 鎖幀 這篇文章引見過,在項目中我們能夠對動畫舉行鎖幀,幀率多是 60 或許 30,假如我們想保證襯着不發抖,在勻速直線運動中,我們只管保證我們設置的速率如果幀率的倍數,或許保證均勻每幀挪動的像素點是一樣的。
在 drawImage
中,不發起運用浮點數舉行定位。