El secreto de las animaciones en JavaScript (requestAnimationFrame())

- Andrés Cruz

In english
El secreto de las animaciones en JavaScript (requestAnimationFrame())

Hemos visto una gran cantidad de recursos en CSS que involucran en común suaves transiciones entre los estado a otro a través de Animaciones y/o Transiciones en CSS.

En esta entrada veremos como crear animaciones con solo JavaScript lo cual puede convertirse en un gran recurso al momento de realizar nuestros desarrollos; crear animaciones con JavaScript es más simple de lo que parece y para ponerlo más interesante esta API está integrada con la API de Canvas lo que aumenta su versatilidad y sencillez en su uso.

Recordando las animaciones "clásicas" en JavaScript

Seguramente las funciones setInterval y setTimeout te suenan de algo; cuando se quería animar, mover o sencillamente ejecutar periódicamente algún script se empleaban estas funciones mencionadas anteriormente; por ejemplo:

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

El problema con estas funciones es que no están optimizadas para realizar animaciones y seguramente en más de una ocasión se ha congelado el navegador por ejecutar algún script en donde tenía presencia estas funciones setInterval y/o setTimeout.

Animando con librerías

También existe la forma más "fácil" que es emplear librerías o plugins en donde nos automatizan el trabajo bastante:

 

Animando un Canvas con Window.requestAnimationFrame()

 

La función que hablábamos en un inicio que permite animar objetos en el Canvas se llama Window.requestAnimationFrame() la cual toma como parámetro a la función que se encarga de pintar (y repintar) -en nuestro caso- el Canvas; por ejemplo, siguiendo el mismo esquema empleado en las "clásicas" animaciones tenemos que:

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

Con la función requestAnimationFrame() se obtienen transiciones o cambios suaves a través de una API que se encuentra optimizado para tal fin.

Animando un cuadrado en Canvas con requestAnimationFrame()

En este pequeño experimento veremos cómo animar un simple cuadrado; en específico haremos que el cuadrado se mueva de una diagonal a la otra; el siguiente código JavaScript hace lo especificado anteriormente:

 
            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();

Analicemos el código presentado anteriormente:

  1. Primero inicializamos los elementos básicos para poder trabajar con Canvas; si no entiendes algunos de los parámetros te invito a que revises el siguiente enlace: Tag Canvas. 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;
  2. Definimos la posición por defecto (o las coordenadas X y Y) en donde es dibujado inicialmente la figura; además es definido un par de variables para especificar la velocidad de la animación. // posiciones var x = width; var y = 0; // velocidad var vx = 3; var vy = 2;
  3. Una de las tareas que realiza la función animar() es la de actualizar las variables x y y con el fin de variar la posición del cuadrado.  // actualizamos la posicion  x -= vx;  y += vy;

Esta sección en fundamental debido a que es donde alteramos la posición del cuadrado lo cual es necesario para realizar la animación.

  1. Invocamos el método requestAnimationFrame(animar); recursivamente especificando como parámetro el nombre de la función (animar()).

Finalmente, la animación con JavaScript:

 

Ver ejemplo Descargar

Con solo quitar el llamado a la función ctx.clearRect() y de esta forma no limpiarel Canvas obtenemos el siguiente resultado:

Refresca para ver la animación.

Ver ejemplo Descargar

Y si alteramos los valores de la "velocidad" para cambiarla entre positiva y negativa y validando que no se salga de rango:

	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:

Ver ejemplo Descargar

Valor devuelto por Window.requestAnimationFrame()

Al invocar la función requestAnimationFrame() la misma devuelve un código distinto de cero que debe ser empleado en caso de querer cancelar la animación:

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

Algunos enlaces de interés:

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.