Animar elementos del DOM

Animaciones nativas con Javascript (Web Animations)


Mediante CSS se pueden crear animaciones CSS muy complejas y potentes. Sin embargo, es posible que en casos donde buscamos cosas muy específicas, necesitemos la potencia de Javascript para poder realizar animaciones avanzadas, ahí es donde entra Web Animations, que no es más que una forma de crear animaciones CSS desde Javascript.

El método animate()

Para crear una animación con WebAnimation usaremos el método .animate(), que se ejecuta sobre un elemento del DOM. Tenemos varias formas de utilizarlo, vamos a verlo en la tabla siguiente y en un ejemplo sencillo para empezar:

MétodoDescripción
.animate(keyframes,duration)Crea y aplica una animación CSS que dura duration segundos.
.animate(keyframes,options)Crea y aplica una animación CSS, con las opciones indicadas en options.

Una vez tenemos el elemento donde queremos aplicar la animación, ejecutamos el método animate() el cual va a tener dos parámetros:

  • El primer parámetro: Un objeto keyframes, que son los fotogramas clave de la animación, con los cambios CSS que se irán aplicando. Equivale a la regla @keyframes de CSS.

  • El segundo parámetro: Un número duration, con la duración en milisegundos de la animación. Más adelante, veremos que este segundo parámetro puede ser también un objeto de opciones, con el que definir cosas más complejas. Lo veremos más adelante.

El siguiente fragmento de código Javascript busca un elemento con clase .element y le aplica una animación que mueve el elemento hacia la derecha, luego hacia abajo, luego hacia la izquierda y luego hacia arriba, al punto de partida. Siempre en cantidades de 200px:

const element = document.querySelector(".element");

const keyframes = [
  { transform: "translate(0, 0)" },
  { transform: "translate(200px, 0)" },
  { transform: "translate(200px, 200px)" },
  { transform: "translate(0, 200px)" },
  { transform: "translate(0, 0)" }
];

element.animate(keyframes, 4000);
body { height: 250px; }

.element {
  width: 50px;
  height: 50px;
  background: indigo;
}
<div class="element"></div>

Esto sería más o menos equivalente a cuando creamos una animación con CSS de la siguiente forma:

@keyframes move {
  0%, 100% { transform: translate(0, 0); }
  40% { transform: translate(200px, 0); }
  60% { transform: translate(200px, 200px); }
  80% { transform: translate(0, 200px); }
}

Si desconoces las animaciones CSS, sería aconsejable primero echar un vistazo antes de continuar, ya que vamos a asumir ciertos conocimientos: Aprender animaciones CSS.

El elemento keyframes

En el ejemplo anterior habrás visto que hemos indicado una constante keyframes, donde está toda la información de la animación. Ese objeto equivale a la regla @keyframes de CSS con sus propiedades CSS en cada uno de los fotogramas clave o intervalos que componen la animación.

Ese parámetro puede pasarse al método .animate() de dos formas. Vamos a analizar estas dos modalidades a continuación.

Modalidad 1: Array de objetos

El parámetro keyframes es un , es decir, un array de objetos, donde cada objeto es un fotograma clave de la animación.

const keyframes = [
  { transform: "translate(0, 0)", opacity: 0, backgroundColor: "#842911" },
  { transform: "translate(200px, 0)", opacity: 1 },
  { transform: "translate(200px, 200px)", opacity: 0.25, backgroundColor: "#840123" },
  { transform: "translate(0, 200px)", opacity: 1 },
  { transform: "translate(0, 0)", opacity: 1 }
];

Observa que cada propiedad de cada objeto es una propiedad CSS, pero escrita en camelCase. En el caso de transform y opacity no hace falta, pero en el caso de la propiedad background-color, en este caso, se reescribe a backgroundColor. Los valores normalmente son de tipo o de tipo , lo que también nos permite interpolar variables o añadir contenido guardado en otras estructuras de datos.

Modalidad 2: Objeto con arrays

El parámetro keyframes también puede indicarse como un , es decir, un objeto donde cada propiedad del mismo contiene un array con los valores de esa propiedad CSS durante cada fotograma clave de la animación.

const keyframes = {
  transform: [
    "translate(0, 0)",
    "translate(200px, 0)",
    "translate(200px, 200px)",
    "translate(0, 200px)"
  ],
  opacity: [0, 1, 0.25, 1],
  backgroundColor: ["#842911", "#840123"]
};

La mecanica es la misma que la anterior, sólo que varía la forma de escribirlo. Utiliza la que mejor se adapte a tus necesidades.

Propiedades del keyframe

Cada objeto de un fotograma clave o intervalo de la animación, aparte de las propiedades CSS transformadas a camelCase, puede tener alguna de las propiedades que comentaremos a continuación. Mediante ellas, podremos establecer particularidades a ese fotograma en cuestión:

PropiedadesDescripción
offsetIndica el porcentaje de cada intervalo en los @keyframes de una animación CSS.
easingIndica la función de tiempo que se aplicará al intervalo concreto de la animación.
compositeIndica la operación de composición que se aplicará en el resto de intervalos.

La propiedad offset nos permite indicar en que momento concreto empieza un intervalo o fotograma clave. Por otro lado, easing nos permite activar una función de tiempo (ritmo) de la animación para un fotograma clave específico. Veremos que también se puede indicar en un objeto de opciones que explicaremos más adelante, y que afecte a todos los fotogramas clave de la animación.

Por último, tenemos composite, que es una operación de composición para el fotograma clave concreto. Hablaremos de esta característica más adelante.

Offset: Inicio del fotograma

Probablemente, te hayas preguntando como puedes variar el instante en el que comienzan cada uno de los fotogramas clave de la animación. En CSS, estableciamos un porcentaje en el interior de las reglas @keyframes que establecían este comienzo.

Aquí, esta información la establecemos en la propiedad offset:

const element = document.querySelector(".element");

const keyframes = [
  { transform: "translate(0, 0)", offset: 0 },
  { transform: "translate(200px, 0)", offset: 0.40 },
  { transform: "translate(200px, 200px)", offset: 0.60 },
  { transform: "translate(0, 200px)", offset: 0.80 }
];

element.animate(keyframes, 4000);

Observa que en este fragmento de código, además de la propiedad transform hemos establecido una propiedad offset para determinar el inicio del fotograma. Dicha propiedad debe contener un valor desde 0 a 1, con decimales. Esta es la equivalencia a los porcentajes. Por ejemplo, si tenemos 80% en la regla @keyframes, la equivalencia en este caso sería un offset de 0.8.

Las propiedades CSS offset y float no se pueden definir ya que coinciden con la propiedad offset que acabamos de mencionar, y con la palabra reservada float, por lo que si queremos establecerlas, debe hacerse como cssOffset y cssFloat.

¿Quién soy yo?

Soy Manz, vivo en Tenerife (España) y soy streamer partner en Twitch y profesor. Me apasiona el universo de la programación web, el diseño y desarrollo web y la tecnología en general. Aunque soy full-stack, mi pasión es el front-end, la terminal y crear cosas divertidas y locas.

Puedes encontrar más sobre mi en Manz.dev