The secret of animations in JavaScript (requestAnimationFrame())

- Andrés Cruz

En español
The secret of animations in JavaScript (requestAnimationFrame())

We have seen a large number of CSS resources that commonly involve smooth transitions between states through Animations and/or Transitions in CSS.

In this entry we will see how to create animations with only JavaScript which can become a great resource when carrying out our developments; creating animations with JavaScript is simpler than it seems and to make it more interesting, this API is integrated with the Canvas API, which increases its versatility and simplicity in use.

Remembering "classic" animations in JavaScript

Surely the setInterval and setTimeout functions sound familiar to you; When you wanted to animate, move or simply periodically execute a script, these functions mentioned above were used; for example:

function draw() {
    setTimeout(pintar, 100);
    // codigo para dibujar
}
pintar();

The problem with these functions is that they are not optimized for animations and surely on more than one occasion the browser has frozen due to executing a script where these setInterval and/or setTimeout functions were present.

Animating with libraries

There is also the "easiest" way, which is to use libraries or plugins where they automate our work quite a bit:

Animating a Canvas with Window.requestAnimationFrame()

The function that we talked about at the beginning that allows you to animate objects on the Canvas is called Window.requestAnimationFrame() which takes as a parameter the function that is responsible for painting (and repainting) - in our case - the Canvas; For example, following the same scheme used in the "classic" animations we have to:

function draw() {
    requestAnimationFrame(draw);
    // Drawing code goes here
}
draw();

With the requestAnimationFrame() function, smooth transitions or changes are obtained through an API that is optimized for this purpose.

Animating a square in Canvas with requestAnimationFrame()

In this little experiment we will see how to animate a simple square; Specifically, we will make the square move from one diagonal to the other; The following JavaScript code does what was specified above:

 
            var canvas = document.getElementById('canvas');
            var ctx = canvas.getContext('2d');

            // obtenemos las dimensiones del canvas
            var width = canvas.width = window.innerWidth;
            var height = canvas.height = window.innerHeight;

            // posiciones
            var x = width;
            var y = 0;

            // velocidad
            var vx = 3;
            var vy = 2;

            // animation loop
            function animar() {
                // limpia canvas
                ctx.clearRect(0, 0, width, height);
                // dibuja un cuadrado de 10x10
                ctx.fillRect(x, y, 10, 10);

                // actualizamos la posicion
                x -= vx;
                y += vy;

                // animamos
                requestAnimationFrame(animar);

                // verificamos que no se salga de rango
                if (y > height || x < 0) {
                    x = width;
                    y = 0;
                }
            }

            animar();

Let's analyze the code presented above:

  1. First we initialize the basic elements to be able to work with Canvas; If you do not understand some of the parameters, I invite you to review the following link: Tag Canvas. var canvas = document.getElementById('canvas'); var ctx = canvas.getContext('2d'); // get the dimensions of the canvas var width = canvas.width = window.innerWidth; var height = canvas.height = window.innerHeight;
  2. We define the default position (or the X and Y coordinates) where the figure is initially drawn; In addition, a couple of variables are defined to specify the speed of the animation. // positions var x = width; var y = 0; // speed var vx = 3; var vy = 2;
  3. One of the tasks performed by the animate() function is to update the variables x and y in order to vary the position of the square. // update the position x -= vx; y += vy;

This section is essential because it is where we alter the position of the square which is necessary to perform the animation.

  1. We invoke the method requestAnimationFrame(animate); recursively specifying the name of the function (animate()) as a parameter.

Finally, the animation with JavaScript:

 

Example Download

By simply removing the call to the ctx.clearRect() function and thus not clearing the Canvas, we obtain the following result:

Refresca para ver la animación.

Example Download

And if we alter the "speed" values to change it between positive and negative and validating that it does not go out of range:

	if(vx > 0){
		  if (x > width) 
			vx *=-1;
		  if (y > height) {
			vx = -8;
		 	vy = 2;
			x=width;
			y=0;
		  }
	}else
		if (x < 0) 
			vx *=-1;
	}

Obtenemos:

Example Download

Value returned by Window.requestAnimationFrame()

When invoking the requestAnimationFrame() function, it returns a non-zero code that must be used if you want to cancel the animation:

id = requestAnimationFrame(callback); 
cancelAnimationFrame(id);

Some links of interest:

Andrés Cruz

Desarrollo con Laravel, Django, Flask, CodeIgniter, HTML5, CSS3, MySQL, JavaScript, Vue, Android, iOS, Flutter

Andrés Cruz en Udemy

Acepto recibir anuncios de interes sobre este Blog.