Skip to content

Instantly share code, notes, and snippets.

@rendfall
Created January 23, 2019 22:10
Show Gist options
  • Save rendfall/6ad6678477faf618a0324c1d80b8c776 to your computer and use it in GitHub Desktop.
Save rendfall/6ad6678477faf618a0324c1d80b8c776 to your computer and use it in GitHub Desktop.
Animation Loop
class AnimationLoop {
constructor(fps = 24) {
this.updateFn = null;
this.id = 0;
this.setFps(fps);
}
onUpdate(fn) {
this.updateFn = fn;
}
setFps(fps) {
this.interval = 1000 / fps;
}
start() {
if (typeof this.updateFn !== 'function') {
throw new Error('You must define update function');
}
let now;
let then = Date.now();
let delta;
const draw = () => {
this.id = requestAnimationFrame(draw);
now = Date.now();
delta = now - then;
if (delta > this.interval) {
// update time stuffs
// Just `then = now` is not enough.
// Lets say we set fps at 10 which means
// each frame must take 100ms
// Now frame executes in 16ms (60fps) so
// the loop iterates 7 times (16*7 = 112ms) until
// delta > interval === true
// Eventually this lowers down the FPS as
// 112*10 = 1120ms (NOT 1000ms).
// So we have to get rid of that extra 12ms
// by subtracting delta (112) % interval (100).
// Hope that makes sense.
then = now - (delta % this.interval);
this.updateFn(delta);
}
}
draw();
}
pause() {
cancelAnimationFrame(this.id);
}
resume() {
this.start();
}
stop() {
this.pause();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment