Why is the element animation in canvas always shaking?

Time:2020-1-30

Source: https://fanmingfei.com/posts/

background

New year’s project encountered a problem that I can’t think of, clearly my frame rate remains at 60 frames, why my animation has been shaking?

My scene is a little sister moving in a uniform straight line.

Previous demo

In this demo, the little sister moves according to x-axis 10px / s and y-axis 30px / s, but her movement is obviously accompanied by shaking.

What’s the matter with this?

Solve

If the y-axis speed of little sister is 10px / s, our frame rate is 60F / s, please calculate:

10 / 60 = 1/6 (px/f)

In fact, the actual speed is 1px every six frames. Of course, there will be jitter. My little sister will stop for a while. It’s always weird~

I simply set my little sister’s moving speed to 100px / s, and found that she still vibrated, thinking that happiness can solve the problem, and found that it is not so simple.

Now that we can count, let’s count

100 / 60 = 10/6 (px/f) = 1.666666....(px/f)

Write a for loop to see where the little sister is in every frame in a second

for(let i = 0; i < 60; i ++) {
  console.log(i*10/6)
}

The output result takes two decimal places as follows:

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

So as a floating-point number, how will canvas be positioned?

Let’s write a demo

Using chrome to open, as a pixel eye, I found that when my little sister was positioned at 50.6px, she had already been rendered to 51px.

So in chrome,drawImageThe position set in will eventually be rounded, which may be related to CSS sub pixel, which will not be explored here first.

So the real position is

 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

From the numerical point of view, the moving distance of each frame may be 1px or 2px, and the little sister may be walking while dancing ballet~

In this case, under the frame rate of 60 frames, setting 60px / s can solve the problem. Try it, really!

summary

This article introduces the lock frame of the front-end animation / game development requestanimationframe. In the project, we may lock the frame of the animation, and the frame rate may be 60 or 30. If we want to ensure that the rendering does not shake, in the uniform linear motion, we try to ensure that the speed we set is a multiple of the frame rate, or that the average pixel points per frame are the same.

staydrawImageFloating point numbers are not recommended for positioning.