Does cancelAnimationFrame
completely removes all the queued up animation logic?
For example, lets say the logic was complicated and my screen was doing 60FPS. the time it took to complete the entire logic per frame, lets say is 50ms. That is much more than 16.66667ms which is the minimum to maintain 60FPS.
If each frame takes 50ms in a total of 60 frames, there would be a build up of the animation logic queue. right?
Normally, at 60fps, with 60 frames, the entire animation should take 1 second. Right?
But with my animation logic, it will take 3 seconds total to complete the animation.
Let's assume, after I start the animation at t0, and I wait until t1.5 while animation is ongoing, and I run the cancelAnimationFrame
function, will it stop the animation right then and there? Or will it complete the entire animation until 3 seconds have passed?
What about if I run the cancelAnimationFrame
function at t0.5? will it stop the animation right then and there? Or will it complete halfway of the animation until 1.5 seconds have passed?
follow up edit for people reading this in the future:
yes. cancelAnimationFrame
does indeed stop the animation immediately as it is called. Yes to both of the above hypothetical questions.
No cancelAnimationFrame(id)
doesn't stop anything.
What it does is it removes the queued callback corresponding to the passed id from the list of animation frame callbacks, so that this callback (and only this one) is never called.
However if the callback has already been executed, or if it's being executed, when cancelAnimationFrame(id)
is called, then it's a no-op: nothing is done.
You can see how the callback keeps being executed even after it called cancelAnimationFrame()
:
const id = requestAnimationFrame(() => {
// When this callback is executed, it has already been removed
// from the list of animation frame callbacks.
cancelAnimationFrame(id); // no-op
// The callback isn't stopped and continues to do whatever it was supposed to do.
console.log("still running");
});
cancelAnimationFrame(id)
makes sense in a context where you either want to stop entirely an animation loop relying on requestAnimationFrame()
, from the outside, or if you want to cancel a one-shot callback, once again from the outside. From the loop itself it's useless, if you don't want to continue the loop, then don't call requestAnimationFrame()
again from that callback.
Regarding your fear of overflowing the queue, this won't happen. when you call requestAnimationFrame(callback)
what it really does is to tell the browser "The next time you will pass data to the compositor, execute that right before.". If you do call requestAnimationFrame(callback)
in that callback, the browser will understand it has to wait for yet the next painting frame, which if you block the engine long enough may indeed be a few monitor's refresh ticks later, but that doesn't matter, it will still be the browser's next painting frame. So your loop will never queue more than one callback per painting frame, the browser will still have time to render and do its things in between, and while you will waste some monitor refreshes, and probably have a junky animation, you won't overflow the animation frames queue.