FPS control

by David Iglesias

HTML

<h3>Throttling requestAnimationFrame to a FPS</h3>
<p>This test:  Results should be ~<span id="targetFps">?</span> fps</p>
<p id="results">Results:</p>
<canvas id="canvas" width=300 height=300></canvas>

JavaScript

var animationId;

startAnimation(5);
setTimeout(() => {
  console.log(`Stopping animation ${animationId}`);
  stopAnimation(animationId); // Nope!
}, 2000);

function stopAnimation(animationId) {
  cancelAnimationFrame(animationId);
}

var fpsInterval;
function startAnimation(fps) {
    fpsInterval = 1000 / fps;
    then = 0;
    animationId = animate();
    targetFps.innerText = fps;
}

var then = 0;
function animate(newMillis) {
  // request another frame
  let animationId = requestAnimationFrame(animate);
  // calc elapsed time since last loop
  let now = newMillis;
  elapsed = now - then;

  // if we're close to the next frame (by ~8ms), do it.
  if (fpsInterval - elapsed <= 8) {
    // Get ready for next frame by setting then=now, but...
    then = now;
    // TESTING...Report #seconds since start and achieved fps.
    results.innerHTML = `<li>Frame time ${elapsed.toFixed(2)} ms. <li>Elapsed time=${now.toFixed(1)}s. <li>Target ms/frame ${fpsInterval.toFixed(2)}. Current FPS: ${(1000 / elapsed).toFixed(2)}`;
  }
  return animationId;
}