Volver a la página principal
miércoles 2 octubre 2024
69

¿Qué es y cómo utilizar la función requestAnimationFrame() en JavaScript?

La función requestAnimationFrame() es una herramienta muy útil en JavaScript que permite a los desarrolladores web ejecutar animaciones de manera eficiente. Esta función proporciona una forma optimizada de realizar animaciones en el navegador, aprovechando mejor los recursos del sistema y mejorando la experiencia del usuario. A continuación, veremos en detalle qué es, cómo funciona y cómo utilizarla correctamente.

¿Qué es requestAnimationFrame()?

requestAnimationFrame() es un método que pertenece al objeto window en JavaScript y se utiliza para programar la actualización de la pantalla antes de la próxima repintada del navegador. Al usar requestAnimationFrame(), le indicamos al navegador que queremos realizar una animación y le pedimos que ejecute una función específica para actualizar la animación antes del próximo *repaint*.

Características de requestAnimationFrame()

1. Sincronización con el repintado del navegador: Se ejecuta justo antes de que el navegador vuelva a dibujar la pantalla, lo que asegura una animación más fluida.

2. Optimización del rendimiento: A diferencia de los métodos setTimeout() o setInterval(), requestAnimationFrame() permite al navegador decidir la frecuencia de ejecución, adaptándose a la capacidad del dispositivo.

3. Ahorro de recursos: Cuando la pestaña está en segundo plano o el navegador no está visible, requestAnimationFrame() pausa la animación, lo que reduce el consumo de recursos y batería.

Sintaxis de requestAnimationFrame()

let requestID = window.requestAnimationFrame(callback);

Parámetro callback

El parámetro callback es una función que se ejecutará antes de que el navegador vuelva a repintar la pantalla. Esta función recibe un argumento que representa el tiempo actual en milisegundos (similar a performance.now()), el cual es útil para medir el rendimiento y ajustar la animación.

Retorno

requestAnimationFrame() devuelve un identificador único (requestID), que se puede utilizar posteriormente para cancelar la animación usando cancelAnimationFrame().

Ejemplo básico de requestAnimationFrame()

Veamos un ejemplo sencillo para entender cómo funciona. Supongamos que queremos mover un cuadro a través de la pantalla de izquierda a derecha.

const box = document.getElementById('box');
let position = 0;

function moveBox(timestamp) {
  position += 2; // Incrementa la posición en cada fotograma
  box.style.transform = `translateX(${position}px)`; // Mueve el cuadro
  if (position < 300) { // Si la posición es menor a 300px, continúa la animación
    requestAnimationFrame(moveBox);
  }
}

requestAnimationFrame(moveBox); // Inicia la animación

Explicación del ejemplo

1. Elemento objetivo: Se selecciona un elemento con el ID box y se define una variable position para rastrear la posición del cuadro.

2. Función moveBox(): Esta función se pasa como *callback* a requestAnimationFrame(). En cada llamada, se incrementa la posición en 2 píxeles y se actualiza la posición de box usando transform.

3. Condición de parada: La animación se detiene cuando la posición es mayor o igual a 300 píxeles.

Comparación con otros métodos de animación

A continuación, compararemos requestAnimationFrame() con otros métodos de animación en JavaScript como setTimeout() y setInterval():

+---------------------------+---------------------------+---------------------------+
|         Método            |    Frecuencia de Ejecución|       Rendimiento         |
+---------------------------+---------------------------+---------------------------+
| requestAnimationFrame()   | Sincronizada con el render | Alta eficiencia, pausa en |
|                           | del navegador (~60 FPS)   | segundo plano.            |
+---------------------------+---------------------------+---------------------------+
| setTimeout(callback, 16)  | Cada 16 ms (~60 FPS)       | No se adapta a cambios de |
|                           |                           | rendimiento del dispositivo|
+---------------------------+---------------------------+---------------------------+
| setInterval(callback, 16) | Cada 16 ms (~60 FPS)       | Continuará ejecutándose   |
|                           |                           | incluso en segundo plano. |
+---------------------------+---------------------------+---------------------------+

Como se puede ver en la tabla anterior, requestAnimationFrame() es superior a los métodos tradicionales en cuanto a eficiencia y sincronización con el navegador. Esto se debe a que se ajusta automáticamente a la frecuencia de actualización del monitor y puede pausar la ejecución cuando la pestaña no está visible.

Uso de cancelAnimationFrame()

Es posible que en algunas ocasiones necesitemos detener una animación en curso. Para esto, utilizamos cancelAnimationFrame(). Este método toma como argumento el identificador de la animación (el valor retornado por requestAnimationFrame()).

Ejemplo de cancelación de animación

let requestID;
let box = document.getElementById('box');
let position = 0;

function moveBox(timestamp) {
  position += 2;
  box.style.transform = `translateX(${position}px)`;

  if (position < 300) {
    requestID = requestAnimationFrame(moveBox);
  } else {
    cancelAnimationFrame(requestID); // Cancela la animación
  }
}

requestID = requestAnimationFrame(moveBox);

En este caso, usamos cancelAnimationFrame(requestID) cuando la posición alcanza 300 píxeles, evitando así que la animación continúe indefinidamente.

Usos avanzados de requestAnimationFrame()

Además de las animaciones básicas, requestAnimationFrame() es ideal para:

1. Juegos en 2D y 3D: Sincroniza los fotogramas del juego con el monitor del usuario.

2. Animaciones complejas: Como transiciones de múltiples elementos o cambios de propiedades CSS.

3. Gráficos interactivos: Como gráficos de datos que requieren actualizaciones constantes basadas en la interacción del usuario.

Ejemplo: Animación de rebote

A continuación, implementaremos una animación de rebote de un círculo usando requestAnimationFrame():

const ball = document.getElementById('ball');
let x = 0;
let y = 0;
let dx = 2; // Velocidad horizontal
let dy = 2; // Velocidad vertical
const container = document.getElementById('container');

function bounceBall() {
  const containerWidth = container.clientWidth;
  const containerHeight = container.clientHeight;

  x += dx;
  y += dy;

  // Verifica colisión con los bordes y cambia la dirección
  if (x + ball.offsetWidth >= containerWidth || x <= 0) {
    dx = -dx;
  }
  if (y + ball.offsetHeight >= containerHeight || y <= 0) {
    dy = -dy;
  }

  ball.style.transform = `translate(${x}px, ${y}px)`;

  requestAnimationFrame(bounceBall);
}

requestAnimationFrame(bounceBall);

Explicación

En este ejemplo, se mueve un círculo (ball) dentro de un contenedor (container). Cada vez que el círculo alcanza los bordes del contenedor, cambia su dirección, creando una animación de rebote fluida y eficiente.

Conclusión

requestAnimationFrame() es la opción preferida para realizar animaciones en JavaScript gracias a su eficiencia y sincronización con el navegador. Al utilizar este método en lugar de los tradicionales setTimeout() o setInterval(), garantizamos que nuestras animaciones sean más fluidas y consuman menos recursos, lo que se traduce en una mejor experiencia para el usuario.

Si deseas llevar tus animaciones al siguiente nivel, te animo a explorar aún más sus capacidades y combinarlas con otras tecnologías como Canvas y WebGL.

Etiquetas:
javascript
Compartir:
Creado por:
Author photo

Jorge García

Fullstack developer