Cómo animar strokes SVG con CSS
Una guía rápida sobre cómo animar strokes SVG con CSS. Consejos, ejemplos y cosas lindas.
Hoy en día, el avance de los navegadores y la gran cantidad de features que estos soportan nos facilita la posibilidad destacar un diseño por medio de una animación. El uso de SVG, transiciones y animaciones de CSS nos abre las puertas a un mundo nuevo, que antes sólo podíamos explorar mediante gifs muy pesados o de mala calidad.
En este artículo te voy a explicar cómo animar un stroke SVG con CSS. Para ilustrar el proceso, voy a tomar como ejemplo un proyecto en el que estuvimos trabajando en Aerolab: el diseño y desarrollo del sitio web de Magic Cube.
Esta es la animación que vamos a aprender hoy:
Si querés verla funcionando en vivo, entrá acá:
En la home de Magic Cube animamos las líneas que unen los diferentes servicios que ofrece la compañía. El objetivo era generar en los usuarios una sensación de conectividad, seguridad y comunicación constante. La animación, por supuesto, no fue casual. Nos ayudaba a transmitir el mensaje que queríamos brindar. Ése es el verdadero poder de las animaciones.
Ahora sí, vamos con la parte práctica.
Tecnologías usadas:
- HTML
- CSS/SASS
- SVG
- Illustrator
Crear la maqueta
Antes de ponernos a escribir la primer línea de código, tenemos que pensar cómo vamos a maquetar el diseño para que se pueda animar.
Para explicar la animación de Magic Cube vamos a utilizar la versión desktop, ya que ésta es la resolución más compleja.
En desktop tenemos cuatro articles al 100%, y su contenido alterna un 50% de izquierda o de derecha.
<section class="product-steps">
<div class="product-steps_container">
<article class="products-step_item"></article>
<article class="products-step_item reverse"></article>
<article class="products-step_item"></article>
<article class="products-step_item reverse"></article>
</div>
</section>
Cada <div class=“product-step_item”> tiene la propiedad display: flex. Cuando el mismo tiene una class “reverse”, su contenido se dispone de manera contraria. Utilizar la propiedad order nos permite reordenar los divs hijos de nuestro <div class=“product-step_item”>.
Colocación de la imagen
Si ponemos la imagen como un background-image del <div class=“product-steps_container”> que contiene a los artículos, nos va a ser imposible animar a menos se trate de un GIF.
En este caso, podríamos haber puesto un <svg> o un <img> en el 50% restante de cada artículo, pero habría sido muy complicado (sin números mágicos) hacer que cada línea de la animación se pegue con el corte de la siguiente imagen.
¡Position al rescate!
Vieja, querida y vapuleada position absolute, volvemos a encontrarnos. Yo siempre te amé ❤
Decidí poner en position relative el <div class=“product-steps_container”> y colocar adentro un PNG en position absolute (top: 0, left: 50%; right: 0, bottom: 0, transform: translate3d(-50%, 0, 0)).
Left: 50% y transform: translate3d(-50%, 0, 0) es un hack muy usado para centrar.
La altura en el <div class=“product-steps_container”> se la da el contenido de cada article. Por eso no tenemos que preocuparnos, ya que el contenido en este sitio no es dinámico.
<section class="product-steps">
<div class="product-steps_container">
<img class="products-steps_background-flash"
src="../images/product-step-background.png" alt="Magic Cube
Background" />
<article class="products-step_item"></article>
<article class="products-step_item reverse"></article>
<article class="products-step_item"></article>
<article class="products-step_item reverse"></article>
</div>
</section>.product-steps_background-flash {
width: 1140px;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
transform: translate3d(-50%, 0, 0 );
}
¿Por qué usamos un PNG?
En este caso elegimos usar un .PNG por la cantidad de detalles que tiene la imagen. Como la imagen incluye transparencias no podíamos usar un JPG. Por otra parte, si utilizábamos un GIF, la imagen iba a perder mucha calidad; y en SVG se veían mal las opacidades.
Preparar el asset
Una vez terminado el maquetado, viene la parte más aburrida: adaptar el asset para que se pueda animar.
Usé Illustrator para limpiar todas las imágenes de la ilustración, y solamente dejé las líneas que se iban a animar.
Es importante aclarar que un animación de este tipo, los elementos que componen al SVG deben tener el atributo stroke, ya que la animación que vamos a utilizar se basa 100% en el que el elemento a animar tenga stroke.
Como vemos en la imagen cada elemento, sea line o polyline, tiene el atributo stroke. Esto es exactamente lo que queremos.
Una vez terminado el asset lo exportamos en SVG, aunque sólo los strokes, que es lo que vamos a animar.
Para hacerme la vida más fácil hice que las medidas del SVG y el PNG sean las mismas. Así, al darle una posición absolute (top: 0, left: 50%; right: 0, bottom: 0, transform: translate3d(-50%, 0, 0)), siempre logro que encajen correctamente.
Una vez realizado esto, le agregamos un glow al stroke, para que parezca mucho más Blade Runner 2049 y tecnológico:
Ahora bien, tenemos que lograr que el stroke se mueva. Básicamente, lo que hacemos acá es que el stroke no sea continuo, sino que sea una línea punteada. Luego, de a poco le vamos sacando la separación entre punto y punto.
.product-steps_svg-flash .svg-stroke {
stroke-dasharray: 500;
animation: dash 4s linear infinite;
}@keyframes dash {
to {
stroke-dashoffset: 0;
}
}
Si algo no te quedó claro, en esta página vas a poder encontrar la explicación detallada de cómo hacer la misma animación.
The End ❤
Para cerrar quiero aclarar que es muy importante que pensemos en el asset desde la etapa de diseño, ya que para poder animarlo vamos a necesitar que esté hecho de ciertas formas específicas. Por esta razón, es fundamental que los desarrolladores participemos también en el proceso de diseño desde el primer día, aprobando y/o proponiendo.
Antes de escribir cualquier tipo de código tenemos que sentarnos delante del diseño y pensar de qué forma podríamos resolverlo para animarlo. El resto es paciencia (sobre todo cuando usamos Illustrator), mucho amor y pasión ❤
Un poco más de Aeromagia✨
Nuestro website — Facebook — Twitter — Instagram