When you tab away, requestAnimationFrame likely stops running. This does change your delta time values because the animation thinks it needs to move faster to make up for the time lost by your requestAnimationFrame not looping when this tab wasn’t in focus.
That’s exactly it. The lastTime gets stale when the tab isn’t active. So when it comes back, the delta calculation goes wild. You could reset lastTime in the if block, or just cap the delta. Capping it is probably safer for any weird edge cases.
Oh, that’s a good call on the stale lastTime. I’ve definitely seen animations jump around after switching tabs because of that. Capping the delta is smart.
That’s a good observation about requestAnimationFrame! You’re right that it often pauses when the tab isn’t active.
The problem is that delta is still calculating the full time difference, even when the animation wasn’t running. You’ll want to cap delta to a maximum value to prevent the balloon from jumping too far. For example, setting delta = Math.min(delta, 1 / 30); would make sure it doesn’t try to catch up too much.
Spot the Bug answer: The animation’s delta time calculation does not account for the time spent when the tab is inactive.
The fix:
Remove `lastTime = timestamp;` from the `if (lastTime === null)` block and initialize `lastTime` to `performance.now()` outside the function.
Why:
When the tab is inactive, requestAnimationFrame pauses. Upon returning to the tab, timestamp will be much larger than lastTime, leading to a huge delta value. This large delta causes the balloon to jump a significant distance, appearing to speed up.
Look. This is why you don’t trust requestAnimationFrame for anything critical unless you’ve got a solid fallback or a way to account for those time jumps. Seen this exact thing cause visual glitches in dashboards.