Lesson 15 - JS requestAnimationFrame - For better drawing

JavaScript Basics JS requestAnimationFrame - For better drawing

The previous lesson, Timers and animations in JavaScript, was about animations. Together with HTML5, a new JavaScript API - requestAnimati­onFrame has been added. It's a technology that allows us to render animations in the browser more fluently and with higher performance. We'll introduce the technology in today's JavaScript tutorial.

If you ever tried to program a simple browser game, your main loop might looked like this.

setInterval(function() {
        update();
        render();
}, 1000 / FPS);

Our previous animations looked very similar, we only combined updating and rendering into a single function. An alternative rendering loop may also look like this:

function loop() {
        setTimeout(loop, 1000 / FPS);
        update();
        render();
}
loop();

The code works, we can even limit FPS. So what's wrong with it?

Wasting computing power

The problem with the code above is that the browser invokes it even if the user is not looking at the page (they switched to another tab or minimized the browser). The Google Chrome browser handles these situations by restricting such loops to only 1 FPS. But this is only its voluntary behavior, and other browsers might not do it. We may experience unnecessary performance drops and discharges on mobile devices.

requestAnimati­onFrame solves it!

Using the requestAnimationFrame() function instead of setTimeout(), our code will look very similarly.

function loop() {
        requestAnimationFrame(loop);
        update();
        render();
}
loop();

Mozilla invented this feature and the WebKit team later took over and improved it. We can use it to draw CSS, DOM elements, WebGL, or on canvas.

Advantages

requestAnimationFrame() will ensure that all of our animations are rendered at once, with higher performance and lower battery consumption.

If you switch to another tab in your browser or you minimize the browser, the rendering will stop to save power and will continue as soon as the page is visible again.

You may have also noticed that using requestAnimationFrame() we have never set the number of FPS. By default, the function uses 60 FPS, but it depends on the browser implementation. However, it should not be too different and it depends on the PC's performance rather than on the browser creator's decision. Also, the support across browsers is quite good.

Demo

At the end, we'll show a simple application in which a square moves on a canvas. We'll implement it using both setInterval() and requestAnimationFrame(). We won't clear the canvas this time on purpose, so we'll see the square's trace.

The solution using setInterval()

window.onload = function() {
        let canvas = document.querySelector("#canvas");
        let context = canvas.getContext("2d");
        let square = {
                "x": 25,
                "y": 25,
                "dirX": -1,
                "dirY": 1,
                "speed": 2,
                "sizeX": 50,
                "sizeY": 50,
                "color": "red"
        };

        function loop() {
                update();
                render();
        }
        setInterval(function() {
                update();
                render();
        }, 1000 / 60);
        loop();


        function update() {
                if (square.x + square.sizeX + square.speed * square.dirX > canvas.width)
                        square.dirX = -1;
                if (square.x + square.speed * square.dirX < 0)
                        square.dirX = 1;
                if (square.y + square.sizeY + square.speed * square.dirY > canvas.height)
                        square.dirY = -1;
                if (square.y + square.speed * square.dirY < 0) square.dirY = 1;

                changeColor();
                square.x += square.speed * square.dirX;
                square.y += square.speed * square.dirY;
        }

        function render() {
                context.fillStyle = square.color;
                context.fillRect(square.x, square.y, square.sizeX, square.sizeY);
        }

        function changeColor() {
                colors = ['green', 'blue', 'red', 'yellow'];
                square.color = colors[Math.floor(Math.random() * colors.length)];
        }
}

The result:

An animation using setInterval
localhost

The solution using requestAnimati­onFrame()

window.onload = function() {
        let canvas = document.querySelector("#canvas");
        let context = canvas.getContext("2d");
        let square = {
                "x": 25,
                "y": 25,
                "dirX": -1,
                "dirY": 1,
                "speed": 2,
                "sizeX": 50,
                "sizeY": 50,
                "color": "red"
        };

        function loop() {
                update();
                render();
                requestAnimationFrame(loop);
        }
        loop();

        function update() {
                if (square.x + square.sizeX + square.speed * square.dirX > canvas.width)        square.dirX = -1;
                if (square.x + square.speed * square.dirX < 0)
                        square.dirX = 1;
                if (square.y + square.sizeY + square.speed * square.dirY > canvas.height)       square.dirY = -1;
                if (square.y + square.speed * square.dirY < 0)
                        square.dirY = 1;

                changeColor();
                square.x += square.speed * square.dirX;
                square.y += square.speed * square.dirY;
        }

        function render() {
                context.fillStyle = square.color;
                context.fillRect(square.x, square.y, square.sizeX, square.sizeY);
        }

        function changeColor() {
                colors = ['green', 'blue', 'red', 'yellow'];
                square.color = colors[Math.floor(Math.random() * colors.length)];
        }
}

The result:

An animation using requestAnimati­onFrame
localhost

I hope the lesson has been useful for you and you will be using requestAnimationFrame() in your animations :)


 

Download

Downloaded 0x (3.33 kB)
Application includes source codes in language JavaScript

 

 

Article has been written for you by David Capka
Avatar
Do you like this article?
1 votes
The author is a programmer, who likes web technologies and being the lead/chief article writer at ICT.social. He shares his knowledge with the community and is always looking to improve. He believes that anyone can do what they set their mind to.
Unicorn College The author learned IT at the Unicorn College - a prestigious college providing education on IT and economics.
Thumbnail
All articles in this section
JavaScript basic constructs
Activities (5)

 

 

Comments

To maintain the quality of discussion, we only allow registered members to comment. Sign in. If you're new, Sign up, it's free.

No one has commented yet - be the first!