marijnh / Eloquent-JavaScript

The sources for the Eloquent JavaScript book
https://eloquentjavascript.net
2.99k stars 790 forks source link

Chapter 14 - Cat animation #539

Closed alexpi closed 3 years ago

alexpi commented 3 years ago

Hi. I don't understand how basing the angle on the difference between the current and last time animate() ran, helps with getting stable motion. If I understand correctly, a lagged animate() run will result in a larger angle for a frame, so the motion will jump ahead a little. Using a fixed angle value per step, the motion would stop, waiting for the function to produce a result. So, both cases will contain some stuttering.

jacekkopecky commented 3 years ago

Hi, I think here it's best to try it: use both versions, and add some kind of every now and then. To add lag, you can use code like this:

setInterval(() => {
  const target = Date.now() + 100;
  while (Date.now() < target) {}
}, 500);

This will wait a 100ms every half a second.

Then you can report whether it's better to have a constant angle per frame, or calculate it by elapsed time.

alexpi commented 3 years ago

Thanks @jacekkopecky! I thought of creating an artificial lag, but couldn't find how. The result confirms in a visual way that each case creates a different kind of stutter. Which case is better is a little subjective I think. So maybe the text "To ensure that the motion of the cat per millisecond is stable" is not very accurate?

jacekkopecky commented 3 years ago

Agreed, jittery in different ways. When I first read the chapter, I understood the "motion [...] is stable" part as stable in time. In animation (especially in games), frame rate sometimes suffers a bit (not in 100ms stutters but more like a frame dropped here and there) but it shouldn't affect the timing of events.

Maybe try it with 20ms delay every 200ms – that should simulate 5 dropped frames every second on a 60fps browser and might provide a different angle at the issue.

marijnh commented 3 years ago

I don't understand how basing the angle on the difference between the current and last time animate() ran, helps with getting stable motion.

It makes sure the rotation speed is constant, regardless of frame rate.