为何 Canvas 内元素动画总是在颤抖?
原文:fanmingfei.com/posts/Why_T…
背景
過年的項目中遇到一個問題讓我百思不得其解,明明我的幀率保持在60幀,為何我的動畫卻一直抖動?
我的場景是一個勻速直線運動的小姐姐。
先上一個 Demo
在這個 Demo 中,小姐姐是按照 x 軸 10px/s,y 軸 30 px/s 進行移動的,不過她的移動是明顯伴隨著抖動的。
這到底是怎么了呢?
解決
如果小姐姐的y軸速度是 10px/s,我們的幀率是 60f/s,計算一下:
10 / 60 = 1/6 (px/f) 復(fù)制代碼實際上,的實際速度是每 6 幀才會移動 1px,這當然會有抖動,小姐姐走一步停一會,總感覺怪怪的~
我索性把小姐姐的移動速度調(diào)快,調(diào)成 100px/s,發(fā)現(xiàn),還是會抖動,以為高高興興能解決了這個問題,發(fā)現(xiàn)還是沒那么簡單。
既然我們能算,那我們就算一算
100 / 60 = 10/6 (px/f) = 1.666666....(px/f) 復(fù)制代碼寫了個for循環(huán),看看一秒中每一幀小姐姐都在什么位置
for(let i = 0; i < 60; i ++) {console.log(i*10/6) } 復(fù)制代碼輸出結(jié)果取小數(shù)點后兩位是這樣的:
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 復(fù)制代碼那么作為浮點數(shù),Canvas 將如何定位呢?
我們來寫一個 Demo
使用 Chrome 打開,作為一個像素眼,我發(fā)現(xiàn),小姐姐定位在 50.6px 的時候,其實就已經(jīng)被渲染到 51px 的位置。
所以在 Chrome 中,drawImage 中設(shè)置的位置最終會被四舍五入,這可能和 CSS Sub-pixel 有關(guān) 這里先不探究。
所以真正的位置其實是
0 2 3 5 7 8 10 12 13 15 17 18 20 22 23 25 27 28 30 3233 35 37 38 40 42 43 45 47 48 50 52 53 55 57 58 60 62 63 6567 68 70 72 73 75 77 78 80 82 83 85 87 88 90 92 93 95 97 98 復(fù)制代碼從數(shù)值來看,每幀移動的距離可能是 1px 也可能是 2px,小姐姐可能是在邊跳芭蕾邊走路嘍~
既然這樣,60 幀的幀率下,設(shè)置 60px/s 就可以解決問題了,嘗試了一下,真的可以!
總結(jié)
前端動畫/游戲開發(fā) requestAnimationFrame 之 鎖幀 這篇文章介紹過,在項目中我們可能對動畫進行鎖幀,幀率可能是 60 或者 30,如果我們想保證渲染不抖動,在勻速直線運動中,我們盡量保證我們設(shè)置的速度要是幀率的倍數(shù),或者保證平均每幀移動的像素點是一樣的。
在 drawImage 中,不建議使用浮點數(shù)進行定位。
總結(jié)
以上是生活随笔為你收集整理的为何 Canvas 内元素动画总是在颤抖?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 统计分析与R软件-chapter2-5
- 下一篇: spring jpa之实体属性类型转换器