Animando SVG con CSS | Programar Plus

No hay una sola forma de animar SVG. Ahí está el <animate> etiqueta que va directamente al código SVG. Hay bibliotecas que ayudan con esto, como Snap.svg o SVG.js. Veremos otra forma: usando SVG en línea (código SVG dentro de HTML) y animando las partes directamente a través de CSS.

Jugué con esto personalmente recientemente, ya que mi Alma mater Wufoo buscaba refrescar el gráfico publicitario que estamos ejecutando aquí. Mi último diseño por aquí usa bastante SVG y pensé que esta sería otra oportunidad perfecta para usarlo un poco más.

El producto terminado es bastante simple. Aquí está:

Vea el anuncio SVG de Pen Wufoo de Chris Coyier (@chriscoyier) en CodePen.

Veamos cómo se hace.

1. Diseñe el anuncio / tenga un plan

Esto puede parecer una forma de dibujar un momento de búho, pero este artículo trata sobre la animación, así que vayamos lo más rápido que podamos.

Mi plan para este anuncio era hacer un anuncio de Wufoo súper simple con su logotipo, colores y marca general clásicos. Luego agrega un poco de estilo.

  1. Haz que las letras salten un poco de la página. Wufoo es una palabra divertida, deja que las letras se diviertan.
  2. En el pasado, hicimos una camiseta con dinosaurios en el frente y en la parte posterior que decía “Rápido. Inteligente. Formidable.” Que son rasgos tanto de los dinosaurios como de Wufoo, sin mencionar el divertido juego de palabras con FORMidble. Hagamos que esos aparezcan y desaparezcan.
  3. Para completar la conexión con el dinosaurio, tendremos una cabeza de T-Rex que se levantará desde la parte inferior con curiosidad y luego se alejará. La palabra “rápido”. entrará cuando se aleje, lo cual es otra pequeña conexión agradable.

Puse todas las partes juntas en Illustrator.

Observe cómo el logotipo y el texto del lema son contornos. Eso significa que son solo formas vectoriales y se renderizarán perfectamente tal como están en el SVG, como <path>s. El texto que ves allí es “Rápido”. se deja como texto en Illustrator.

Cuando guarde esto de Illustrator, quedará como un <text> elemento.

2. Guardar como SVG

Illustrator puede guardar esto directamente como SVG:

Puede abrir ese archivo SVG en un editor de código y ver el código SVG:

3. Limpiar el SVG, dar clases de formas

Es posible que desee ejecutarlo a través de SVGO para optimizarlo y eliminar el DOCTYPE y esas cosas. Pero lo que es más importante para esta publicación, querrá darles nombres de clases a las diferentes formas, de esa manera podemos seleccionarlas en CSS y hacer cosas.

<svg version="1.1" id="wufoo-ad" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 400 400" enable-background="new 0 0 400 400" xml:space="preserve">

  <!-- background -->
  <rect class="wufoo-background" fill="#D03E27" width="400" height="400" />

  <!-- logo letters -->
  <path class="wufoo-letter" fill="#F4F4F4" d="M60.858,129...." />
  <path class="wufoo-letter" fill="#F4F4F4" d="..." />
     <!-- etc -->

  <!-- dinosaur -->
  <g class="trex">
     <path ... />
     <path ... />
  </g>

</svg>

4. Inserta el SVG

Puede copiar y pegar ese SVG directamente en el HTML donde desee el anuncio. Pero eso probablemente arruinará la plantilla. Con toda probabilidad, harás algo como:

<aside class="sidebar">
  
   <div class="module module-ad">
      
       <?php include("ads/wufoo.svg"); ?>

   </div>

   ...

5. ¡Animar!

Ahora que tenemos estas formas en el DOM que podemos apuntar y diseñar como cualquier otro elemento HTML, hagámoslo.

Digamos que queremos hacer esto como Línea de tiempo de 10 segundos.

Las palabras se desvanecen primero

Lo primero que queremos que suceda es el ayuno. Inteligente. Formidable. cosa. Cada palabra se mostrará durante un segundo. Así que haremos una animación en la que la palabra se muestre el 10% del tiempo:

@keyframes hideshow {
  0% { opacity: 1; }
  10% { opacity: 1; }
  15% { opacity: 0; }
  100% { opacity: 0; }
} 

Luego, apunte a esa primera palabra y haga que la animación dure 10 segundos (el 10% de eso es 1 segundo):

.text-1 {
  animation: hideshow 10s ease infinite;
}

Las siguientes dos letras comenzarán ocultas (opacity: 0;) y luego use exactamente la misma animación, solo que se retrasó para comenzar un poco más tarde:

.text-2 {
  opacity: 0;
  animation: hideshow 10s 1.5s ease infinite;
}
.text-3 {
  opacity: 0;
  animation: hideshow 10s 3s ease infinite;
}

Los 0.5 segundos adicionales en cada uno son para acomodar el período de tiempo de desvanecimiento de la palabra anterior.

Estallidos de letras

Tan pronto como esas letras terminen de animarse, tendremos las letras en WUFOO haciendo su jiggle jump, así:

El truco aquí es que haremos la animación de solo 5 segundos de duración, pero la ejecutaremos una vez hacia adelante y una vez hacia atrás. De esa manera, coincide con nuestra línea de tiempo de 10 segundos, se coloca justo en el medio donde lo queremos y solo necesitamos escalar en una dirección, porque cuando se invierte, se reducirá.

Cada letra tiene un poco de retraso, por lo que se desvían un poco:

.wufoo-letter {
  animation: kaboom 5s ease alternate infinite;
  &:nth-child(2) {
    animation-delay: 0.1s;
  }
  &:nth-child(3) {
    animation-delay: 0.2s;
  }
  &:nth-child(4) {
    animation-delay: 0.3s;
  }
  &:nth-child(5) {
    animation-delay: 0.4s;
  }
}
@keyframes kaboom {
  90% {
    transform: scale(1.0);
  }
  100% {
    transform: scale(1.1);
  }
}

Lo anterior está en SCSS solo por brevedad y no incluye ningún prefijo (como lo necesitaría en producción).

me siento como animation-delay es una propiedad que se beneficiaría de la aleatorización nativa en CSS. Sería bueno ver que las letras se retrasan aleatoriamente solo un poco cada vez.

Dinosaurio último

Tan pronto como terminen las palabras, el dinosaurio levantará la cabeza. Aunque el dinosaurio se compone de muchos <path>s, podemos orientarlos a todos juntos dirigiéndonos a los <g> (grupo) etiqueta que los envuelve a todos.

Debido a que es mejor usar traducir a la posición animada, lo haremos en los fotogramas clave:

@keyframes popup {
  0% {
    transform: translateY(150px);
  }
  34% {
    transform: translateY(20px);
  }
  37% {
    transform: translateY(150px);
  }
  100% {
    transform: translateY(150px);
  }
}

Queríamos que esta animación “durara” unos 3 segundos. En realidad, se ejecuta en bucles de 10 segundos, pero solo lo verá hacer cosas durante 3 segundos. Cuando el translateY (150px) está en efecto, el dinosaurio se mueve tan abajo que no ves nada. En el 37% de esa animación (alrededor de 3 segundos), lo habrá visto moverse lentamente hacia arriba y luego hacia abajo rápidamente).

Cuando apliquemos esta animación, nos aseguraremos de que:

El dinosaurio está escondido al principio.
La animación se retrasa, por lo que comienza justo después de que las palabras terminan con su baile de entrada / salida.

.trex {
  transform: translateY(150px);
  animation: popup 10s 6.5s ease infinite;
}

El dinosaurio aparece justo en el último segundo, que es cuando aparece la palabra “Rápido”. vuelve a aparecer en la pantalla (porque todas las animaciones están configuradas para infinite, que los vuelve a ejecutar para siempre). Eso es un poco de sinergia divertida.

6. Cómo convertirlo en un anuncio adaptable o en el que se puede hacer clic

Una de las cosas hermosas de SVG es que se puede escalar a cualquier tamaño sin perder calidad. Para hacer un SVG en línea como esta escala mientras se mantiene su relación de aspecto, podemos usar la vieja técnica del cuadro acolchado.

<div class="wufoo-ad-wrap">
  <svg class="wufoo-ad">
     ...
  </svg>
</div>
.wufoo-ad-wrap {
  height: 0;
  padding-top: 100%;
  position: relative;
}
.wufoo-ad {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

La idea aquí es que la “envoltura” siempre será un cuadrado perfecto, en relación con su ancho. Luego colocamos absolutamente el SVG dentro de ese cuadrado perfecto, que felizmente cambiará de tamaño.

Dado que se trata de un anuncio (en el que, por supuesto, se debería poder hacer clic), en lugar de utilizar un <div> para la envoltura, podría usar un <a href="">, solo asegúrate de configurarlo para que sea display: block;.

Cosa final, como referencia.

Creo que hay un futuro para este tipo de cosas en la publicidad gráfica, particularmente debido al control CSS y al cambio de tamaño fácil y nítido.