Vanilla JavaScript physics animation with requestAnimationFrame
2025-01-14
I don’t know if it’s just me (being a trained physicist after all), but I find myself wanting to animate something on the web in a way that feels like real physics pretty often. Usually, my inner monologue goes like this:
- Can I do that with CSS
transformoderanimation? - Can I do that with the JavaScript
.animate()function (i.e. the Web Animation API)? - Can I do it with
setTimeout()orsetInterval()(using the methods above)? - Should I really try to animate the thing myself using
requestAnimationFrame()?
The few times I get to step 4, I use a setup that reads something like that:
let animationFrame = null;
let t0 = 0;
let dt = 0;
let v = 10;
let s = 0;
// start animation
animationFrame = requestAnimationFrame(updatePhysics);
function updatePhysics(t1) {
// timestep update
if (t0 == null) dt = 1000/60;
else dt = t1 - t0;
t0 = t1;
// physics parameter update
const a = -9.81;
v += a * dt;
s += v * dt;
// boundary conditions
console.log('position', s);
if ((v > 0 && v < 0.01) && Math.abs(s) < 0.1 && animationFrame != null) {
cancelAnimationFrame(animationFrame);
}
animationFrame = requestAnimationFrame(updatePhysics);
}