# Throttling (aka Forcing a Framerate on) requestAnimationFrame!

**URL:** <https://forum.kirupa.com/t/throttling-aka-forcing-a-framerate-on-requestanimationframe/636753>\
**Category:** Uncategorized\
**Created:** [June 12, 2017, 2:41am UTC](https://forum.kirupa.com/t/throttling-aka-forcing-a-framerate-on-requestanimationframe/636753 "2017-06-12T02:41:21Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![kirupa](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/kirupa/32/11616_2.png) [@kirupa](https://forum.kirupa.com/u/kirupa)\
**Post date:** [June 12, 2017, 2:41am UTC](https://forum.kirupa.com/t/throttling-aka-forcing-a-framerate-on-requestanimationframe/636753/1 "2017-06-12T02:41:21Z")

</div>

With devices (like the new iPad) featuring displays over 60Hz, there is a good chance that browsers will be running at rates greater than 60Hz as well. That’s great for everyone except those of us who used `requestAnimationFrame` thinking that rates will stay fixed at 60Hz,

To force a frame rate, check out the following snippet:

```
var currentTime;
var elapsedTime;
var startTime;

// set the frame rate you want!
var fps = 60;

var interval = 1000 / fps;

function loop() {
  currentTime = performance.now();
  elapsedTime = currentTime - startTime;

  if (elapsedTime > interval) {
    // this seems weird, but it is done to account for
    // the time it takes to display a frame
    startTime = currentTime - (elapsedTime % interval);

    //
    // Your animation code goes below!
    //
  }
  requestAnimationFrame(loop);
}

// Start the timer!
function start() {
  startTime = performance.now();
  requestAnimationFrame(loop);
}
start();

```

I’ll write this up more formally with some examples shortly, but this may help for now 🙂

If you have no idea what I am talking about, read up on `requestAnimationFrame` [in this tutorial](https://www.kirupa.com/html5/animating_with_requestAnimationFrame.htm).

Cheers,  
Kirupa

---

<div class="post-metadata">

**Author:** ![kirupa](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/kirupa/32/11616_2.png) [@kirupa](https://forum.kirupa.com/u/kirupa)\
**Post date:** [June 15, 2017, 6:07am UTC](https://forum.kirupa.com/t/throttling-aka-forcing-a-framerate-on-requestanimationframe/636753/2 "2017-06-15T06:07:05Z")

</div>

Here is an example of this code in action:

```
<!DOCTYPE html>
<html>

<head>
  <title>requestAnimationFrame Throttling Example</title>
  <style>
    body {
      margin: 50px;
    }
    #myCanvas {
      border: 5px solid #EEE;
    }
    #container p {
      font-family: sans-serif;
      font-size: 12pt;
    }
    #container div p {
      display: inline-block;
    }
    #fpsDropdown {
      font-size: 16px;
      font-weight: bold;
    }
  </style>
</head>

<body>
  <div id="container">
      <canvas id="myCanvas" height="400" width="400"></canvas>
      <div>
        <p>Frames per second:</p>
        <select id="fpsDropdown">
          <option value="1">1</option>
          <option value="5">5</option>
          <option value="15">15</option>
          <option value="30">30</option>
          <option selected="selected" value="60">60</option>
          <option value="120">120</option>
          <option value="240">240</option>
        </select>
      <div>
  </div>

  <script>

    var currentTime;
    var elapsedTime;
    var startTime;

    // set the frame rate you want!
    var fps = 60;

    var interval = 1000 / fps;

    var mainCanvas = document.querySelector("#myCanvas");
    var mainContext = mainCanvas.getContext('2d');

    var canvasWidth = mainCanvas.width;
    var canvasHeight = mainCanvas.height;

    var selector = document.querySelector("#fpsDropdown");
    selector.addEventListener("change", updateFPS, false);

    function updateFPS(e) {
      var selectIndex = selector.options.selectedIndex;
      fps = parseInt(selector.options[selectIndex].value);
      interval = 1000 / fps;

      console.log("New fps is: " + fps);

      start();
    }

    // this array contains a reference to every circle that you will create
    var circles = new Array();

    //
    // The Circle "constructor" is responsible for creating the circle
    // objects and defining the various properties they have
    //
    function Circle(angle, sign, radius, rotationRadius, initialX, initialY) {
        this.angle = angle;
        this.sign = sign;
        this.radius = radius;
        this.rotationRadius = rotationRadius;
        this.initialX = initialX;
        this.initialY = initialY;
        this.incrementer = .01 + Math.random() * .1;
    }

    Circle.prototype.update = function () {

        this.angle += this.incrementer;

        this.currentX = this.initialX + this.rotationRadius * Math.cos(this.angle);
        this.currentY = this.initialY + this.rotationRadius * Math.sin(this.angle);

        if (this.angle >= (Math.PI * 2)) {
            this.angle = 0;
            this.incrementer = .01 + Math.random() * .1;
        }

        // The following code is responsible for actually drawing the circle
        mainContext.beginPath();
        mainContext.arc(this.currentX, this.currentY, this.radius,
                        0, Math.PI * 2, false);
        mainContext.closePath();
        mainContext.fillStyle = 'rgba(0, 51, 204, .1)';
        mainContext.fill();
    };

    //
    // This function creates the circles that you end up seeing
    //
    function createCircles() {
        // change the range of this loop to adjust the number of circles you see
        for (var i = 0; i < 50; i++) {
            var radius = 5 + Math.random() * 100;
            var initialX = canvasWidth / 2;
            var initialY = canvasHeight / 2;
            var rotationRadius = 1 + Math.random() * 30;
            var angle = Math.random() * 2 * Math.PI;

            var signHelper = Math.floor(Math.random() * 2);
            var sign;

            // Randomly specify the direction the circle will be rotating
            if (signHelper == 1) {
                sign = -1;
            } else {
                sign = 1;
            }

            // create the Circle object
            var circle = new Circle(angle,
                                    sign,
                                    radius,
                                    rotationRadius,
                                    initialX,
                                    initialY);
            circles.push(circle);
        }
        // call the draw function approximately 60 times a second
        start();
    }
    createCircles();

    function loop() {
      currentTime = performance.now();
      elapsedTime = currentTime - startTime;

      if (elapsedTime > interval) {
        // this seems weird, but it is done to account for
        // the time it takes to display a frame
        startTime = currentTime - (elapsedTime % interval);

        mainContext.clearRect(0, 0, canvasWidth, canvasHeight);
        mainContext.fillStyle = '#F6F6F6';
        mainContext.fillRect(0, 0, canvasWidth, canvasHeight);

        for (var i = 0; i < circles.length; i++) {
            var circle = circles[i];
            circle.update();
        }
      }
      requestAnimationFrame(loop);
    }

    // Start the timer!
    function start() {
      startTime = performance.now();
      requestAnimationFrame(loop);
    }
    start();
  </script>

</body>

</html>
```

---

<div class="post-metadata">

**Author:** ![krilnon](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/krilnon/32/34_2.png) [@krilnon](https://forum.kirupa.com/u/krilnon)\
**Post date:** [June 16, 2017, 6:00am UTC](https://forum.kirupa.com/t/throttling-aka-forcing-a-framerate-on-requestanimationframe/636753/3 "2017-06-16T06:00:26Z")

</div>

> [@kirupa](#):
>
> // set the frame rate you want!  
> var fps = 60;

I think it’d be useful to provide advice on when & why someone would pick a particular frame rate. When do I pick 120, 60, 30, 24, 12, etc.

---

<div class="post-metadata">

**Author:** ![kirupa](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/kirupa/32/11616_2.png) [@kirupa](https://forum.kirupa.com/u/kirupa)\
**Post date:** [June 16, 2017, 3:46pm UTC](https://forum.kirupa.com/t/throttling-aka-forcing-a-framerate-on-requestanimationframe/636753/4 "2017-06-16T15:46:42Z")

</div>

Good point! I’ll be sure to mention that in the article 🙂
