Cómo animar en la Web con GreenSock »Wiki Ùtil Programar Plus

Realmente hay miles de formas de animar en la web. Hemos cubierto una comparación de diferentes tecnologías de animación aquí antes. Hoy, vamos a sumergirnos en una guía paso a paso de una de mis formas favoritas de hacerlo: usando GreenSock.

(No me pagan ni nada, simplemente disfruto usándolos).

¿Por qué prefiero GreenSock a otros métodos? Técnicamente hablando, a menudo es la mejor herramienta para el trabajo. Su uso es extremadamente sencillo, incluso para movimientos complejos. Aquí hay algunas razones más por las que prefiero usarlo:

  • Puede usarlos en elementos DOM, así como dentro de contextos WebGL / Canvas / Three.js.
  • La relajación es muy sofisticada. Las animaciones CSS están limitadas a dos controles Bézier para mayor facilidad, lo que significa que si desea, por ejemplo, un efecto de rebote, tendrá que hacer fotogramas clave hacia arriba y hacia abajo y hacia arriba y hacia abajo en cada pasada. GreenSock permite varios controles Bézier para crear efectos avanzados. Un rebote es una sola línea de código. Puedes ver lo que quiero decir al ver su visualizador de facilidad.
  • Puede secuenciar el movimiento en una línea de tiempo. Las animaciones CSS pueden volverse un poco espaguetis cuando tienes que coordinar varias cosas a la vez. GreenSock sigue siendo muy legible y le permite controlar la propia línea de tiempo. ¡Incluso puedes animar tus animaciones! 🤯
  • Realizará algunos cálculos bajo el capó para evitar un comportamiento extraño entre navegadores, así como las cosas que las especificaciones dictan que deberían ser ciertas, como la forma en que funcionan las transformaciones de apilamiento.
  • Ofrece una gran cantidad de funciones avanzadas, en forma de complementos, que puede usar si desea llevar su trabajo un paso más allá: cosas como transformar formas SVG, dibujar rutas SVG, arrastrar y soltar, inercia y más.

La gente a veces me pregunta por qué usaría esta biblioteca en particular sobre todas las otras opciones. Está más avanzado que la mayoría de los demás: han existido desde que Flash todavía existía. Este carrete de demostración es bastante inspirador y también transmite el punto de que los animadores web serios tienden a utilizar esta herramienta:

Lo que sigue es un desglose de cómo crear movimiento en la web, destilado hasta las unidades más pequeñas que pude hacer. ¡Empecemos!

Animando un elemento DOM

Considere una pelota que hacemos con un <div> que tiene estilo con un border-radius valor del 50%. Así es como lo escalaríamos y moveríamos con GreenSock:

<div class="ball"></div>
gsap.to('.ball', {
  duration: 1,
  x: 200,
  scale: 2
})

En este caso, le estamos diciendo a GreenSock (gsap) para tomar el elemento con la clase de .ball Muévelo .to() algunas propiedades diferentes. Hemos acortado las propiedades CSS de transform: translateX(200px) a un aerodinámico x: 200 (tenga en cuenta que no hay necesidad de las unidades, pero puede pasarlas como una cadena). Tampoco estamos escribiendo transform: scale(2). Aquí hay una referencia de las transformaciones que podría querer usar con animaciones y su sintaxis CSS correspondiente:

x: 100 // transform: translateX(100px)
y: 100 // transform: translateY(100px)
z: 100 // transform: translateZ(100px)
// you do not need the null transform hack or hardware acceleration, it comes baked in with
// force3d:true. If you want to unset this, force3d:false
scale: 2 // transform: scale(2)
scaleX: 2 // transform: scaleX(2)
scaleY: 2 // transform: scaleY(2)
scaleZ: 2 // transform: scaleZ(2)
skew: 15 // transform: skew(15deg)
skewX: 15 // transform: skewX(15deg)
skewY: 15 // transform: skewY(15deg)
rotation: 180 // transform: rotate(180deg)
rotationX: 180 // transform: rotateX(180deg)
rotationY: 180 // transform: rotateY(180deg)
rotationZ: 180 // transform: rotateZ(180deg)
perspective: 1000 // transform: perspective(1000px)
transformOrigin: '50% 50%' // transform-origin: 50% 50%

La duración es lo que podría pensar que es: es un lapso de tiempo de un segundo.

Entonces, está bien, ¿cómo animaríamos, digamos, un SVG? Consideremos el mismo código anterior como SVG:

<svg viewBox="0 0 500 400">
  <circle class="ball" cx="80" cy="80" r="80" />
</svg>
gsap.to('.ball', {
  duration: 1,
  x: 200,
  scale: 2
})

Desde una perspectiva de animación, en realidad es exactamente lo mismo. Está agarrando el elemento con la clase. .ball sobre él, y traduciendo esas propiedades. Dado que los SVG son literalmente elementos DOM, podemos colocar una clase en cualquiera de ellos y animarlos de la misma manera.

¡Estupendo! Cocinamos con gas.

Facilita

Mencioné antes que las facilidades son una de mis funciones favoritas, echemos un vistazo a cómo las usaríamos.

Tomemos la bola original. Tal vez queramos probar una de esas facilidades de rebote más exclusivas. Sería así:

gsap.to('.ball', {
  duration: 1.5,
  x: 200,
  scale: 2,
  ease: 'bounce'
})

¡Eso es! Esta versión de GreenSock asume que desea utilizar ease-out tiempo (que es mejor para las entradas), por lo que se aplica de forma predeterminada. Todo lo que tienes que hacer es especificar “rebote” como una cuerda y estarás listo para las carreras.

Es posible que haya notado que también alargamos un poco la duración. Eso es porque la pelota tiene que hacer más “trabajo” entre los estados inicial y final. Una duración de un segundo, aunque encantadora para la relajación lineal o sinusoidal, es demasiado rápida para un rebote o una facilidad elástica.

Retrasos y cronogramas

Mencioné que el valor predeterminado ease-out La función de cronometraje es buena para las entradas. ¿Qué tal un ease-in ¿O salida fácil de entrar y salir? Hagámoslo también.

gsap.to('.ball', {
  duration: 1.5,
  x: 200,
  scale: 2,
  ease: 'bounce'
})

gsap.to('.ball', {
  duration: 1.5,
  delay: 1.5,
  x: 0,
  scale: 1,
  ease: 'back.inOut(3)'
})

Es posible que haya notado que suceden algunas cosas. Por ejemplo, no usamos bounce.in en la penúltima línea (ease: 'back.inOut(3)'). En cambio, usamos otra facilidad llamada back por ease-in-out. También pasamos una opción de configuración porque, como puede ver con la herramienta de visualización de facilidad de Greensock, no estamos limitados solo a la configuración predeterminada para esa facilidad. Podemos ajustarlo a nuestras necesidades. ¡Limpio!

También puede haber notado que encadenamos las animaciones usando un retraso. Tomamos la duración de la primera animación y nos aseguramos de que la siguiente tenga un retraso que coincida. Eso funciona aquí, pero es bastante frágil. ¿Y si queremos cambiar la longitud del primero? Bueno, ahora tenemos que retroceder y cambiar el retraso que sigue. ¿Y si tenemos otra animación después de eso? ¿Y otro después de eso? Bueno, tendríamos que volver atrás y calcular todos los demás retrasos en el futuro. Eso es mucho trabajo manual.

Podemos descargar ese trabajo a la computadora. ¡Algunas de mis animaciones más complejas son cientos de animaciones encadenadas! Si termino mi trabajo y quiero ajustar algo al principio, no quiero tener que repasar todo. Ingrese líneas de tiempo:

gsap
  .timeline()
  .to('.ball', {
    duration: 1.5,
    x: 200,
    scale: 2,
    ease: "bounce"
  })
  .to('.ball', {
    duration: 1.5,
    x: 0,
    scale: 1,
    ease: "back.inOut(3)"
  });

Esto crea una instancia de una línea de tiempo y luego encadena las dos animaciones fuera de ella.

Pero todavía tenemos un poco de repetición donde seguimos usando la misma duración en cada animación. Creemos un valor predeterminado para eso como una opción pasada a la línea de tiempo.

gsap
  .timeline({
    defaults: {
      duration: 1.5
    }
  })
  .to('.ball', {
    x: 200,
    scale: 2,
    ease: "bounce"
  })
  .to('.ball', {
    x: 0,
    scale: 1,
    ease: "back.inOut(3)"
  });

¡Eso es muy bonito! Muy bien, probablemente estés empezando a ver cómo se construyen las cosas de esta manera. Si bien puede que no sea un gran problema en una animación así de simple, los valores predeterminados y las líneas de tiempo en animaciones realmente complejas pueden mantener el código realmente mantenible.

Ahora, ¿qué pasa si queremos reflejar este movimiento en la otra dirección con la pelota, y simplemente … mantenerlo en marcha? En otras palabras, ¿y si queremos un bucle? Ahí es cuando agregamos repeat: -1, que se puede aplicar a una sola animación oa toda la línea de tiempo.

gsap
  .timeline({
    repeat: -1,
    defaults: {
      duration: 1.5
    }
  })
  .to('.ball', {
    x: 200,
    scale: 2,
    ease: "bounce"
  })
  .to('.ball', {
    x: 0,
    scale: 1,
    ease: "back.inOut(3)"
  })
  .to('.ball', {
    x: -200,
    scale: 2,
    ease: "bounce"
  })
  .to('.ball', {
    x: 0,
    scale: 1,
    ease: "back.inOut(3)"
  });

También podríamos no solo hacer que se repita, sino que se repita y se reproduzca y siga adelante, como un yoyo. Por eso lo llamamos yoyo: verdad. Para aclarar el punto, mostraremos esto solo con la primera animación. Puede ver que se reproduce hacia adelante y luego hacia atrás.

gsap
  .timeline({
    repeat: -1,
    yoyo: true,
    defaults: {
      duration: 1.5
    }
  })
  .to('.ball', {
    x: 200,
    scale: 2,
    ease: "bounce"
  })

Superposiciones y etiquetas

Es genial que podamos encadenar animaciones con facilidad, pero el movimiento de la vida real no funciona exactamente de esta manera. Si cruza la habitación para tomar un vaso de agua, no camina. Luego se detiene. Luego recoge el agua. Entonces bébalo. Es más probable que hagas las cosas en un movimiento continuo. Así que hablemos brevemente sobre cómo superponer el movimiento y hacer que las cosas se disparen a la vez.

Si queremos estar seguros de que las cosas se disparan un poco antes y después de la otra en una línea de tiempo, podemos usar un incrementador o decrementador. Si tomamos el siguiente ejemplo que muestra tres bolas animándose una tras otra, se siente un poco rígido.

gsap
  .timeline({
    defaults: {
      duration: 1.5
    }
  })
  .to('.ball', {
    x: 300,
    scale: 2,
    ease: "bounce"
  })
  .to('.ball2', {
    x: 300,
    scale: 2,
    ease: "bounce"
  })
  .to('.ball3', {
    x: 300,
    scale: 2,
    ease: "bounce"
  })

Las cosas se vuelven más suaves si superponemos el movimiento ligeramente usando esos decrementadores pasados ​​como cadenas:

gsap
  .timeline({
    defaults: {
      duration: 1.5
    }
  })
  .to('.ball', {
    x: 300,
    scale: 2,
    ease: "bounce"
  })
  .to('.ball2', {
    x: 300,
    scale: 2,
    ease: "bounce"
  }, '-=1')
  .to('.ball3', {
    x: 300,
    scale: 2,
    ease: "bounce"
  }, '-=1')

Otra forma en que podemos hacer esto es usando algo llamado etiqueta. Las etiquetas se aseguran de que las cosas se activen en un momento determinado en el cabezal de reproducción de la animación. Se parece a esto:.add('labelName')

gsap
  .timeline({
    defaults: {
      duration: 1.5
    }
  })
  .add('start')
  .to('.ball', {
    x: 300,
    scale: 2,
    ease: "bounce"
  }, 'start')
  .to('.ball2', {
    x: 300,
    scale: 2,
    ease: "bounce"
  }, 'start')
  .to('.ball3', {
    x: 300,
    scale: 2,
    ease: "bounce"
  }, 'start') 

Incluso podemos incrementar y disminuir a partir de la etiqueta. De hecho, hago mucho esto en mis animaciones. Se parece a esto'start+=0.25'.

gsap
  .timeline({
    defaults: {
      duration: 1.5
    }
  })
  .add('start')
  .to('.ball', {
    x: 300,
    scale: 2,
    ease: "bounce"
  }, 'start')
  .to('.ball2', {
    x: 300,
    scale: 2,
    ease: "bounce"
  }, 'start+=0.25')
  .to('.ball3', {
    x: 300,
    scale: 2,
    ease: "bounce"
  }, 'start+=0.5') 
 

¡Uf! ¡Podemos hacer mucho con esto! Aquí hay un ejemplo de una animación que reúne muchas de estas premisas, con un poco de interacción usando JavaScript vanilla. Asegúrese de hacer clic en la campana.

Si está buscando más animación basada en marcos con GreenSock, aquí hay un artículo que escribí que cubre esto en Vue, y una charla que di que aborda React: tiene un par de años, pero las premisas básicas aún se aplican.

Pero todavía hay muchas cosas que no hemos cubierto, incluidos los escalonamientos, la transformación de SVG, el dibujo de SVG, el lanzamiento de cosas por la pantalla, el movimiento de cosas a lo largo de un camino, la animación de texto … ¡lo que sea! Sugeriría dirigirse a la documentación de GreenSock para obtener esos detalles. También tengo un curso sobre Frontend Masters que cubre todos estos con mucha más profundidad y los materiales son de código abierto en mi GitHub. También tengo muchos bolígrafos que son de código abierto para que puedas jugar con ellos.

Espero que esto te ayude a empezar a trabajar con animaciones en la web. ¡No puedo esperar a ver lo que haces!

(Visited 4 times, 1 visits today)