Cómo utilizar WAAPI para crear una biblioteca de animaciones

La API de animaciones web nos permite construir animaciones y controlar su reproducción con JavaScript. La API abre el motor de animación del navegador a los desarrolladores y fue diseñada para ser la base de las implementaciones de animaciones y transiciones CSS, dejando la puerta abierta a futuros efectos de animación. Es una de las formas más eficaces de animar en la Web, ya que permite que el navegador realice sus propias optimizaciones internas sin hackeos, coerción o window.requestAnimationFrame()
.
Con la API de animaciones web, podemos mover animaciones interactivas de hojas de estilo a JavaScript, separando la presentación del comportamiento. Ya no necesitamos depender de técnicas pesadas de DOM, como escribir propiedades CSS y clases de alcance en elementos para controlar la dirección de reproducción. Y a diferencia del CSS declarativo puro, JavaScript también nos permite establecer dinámicamente valores desde propiedades hasta duraciones. Para crear bibliotecas de animación personalizadas y crear animaciones interactivas, la API de animaciones web puede ser la herramienta perfecta para el trabajo. ¡Veamos qué puede hacer!
Durante el resto de este artículo, a veces me referí a la API de animación web como WAAPI. Al buscar recursos en la API de animación web, es posible que se pierda al buscar “API de animación web”, por lo que, para facilitar la búsqueda de recursos, creo que deberíamos adoptar el término WAAPI; Dime lo que piensas en los comentarios a continuación.
Esta es la biblioteca que hice con WAAPI
@okikio/animate es una biblioteca de animación para la web moderna. Se inspiró en animateplus y animejs; se centra en el rendimiento y la experiencia del desarrollador, y utiliza la API de animación web para ofrecer animaciones fluidas en un tamaño pequeño, con un peso de ~5,79 KB (minimizado y comprimido con gzip).
La historia detrás de @okikio/animate
En 2020, decidió crear una biblioteca PJAX más eficiente, similar al proyecto Starting Blocks de Rezo Zero, pero con la facilidad de uso de barbajs. Sentí que los bloques iniciales eran más fáciles de ampliar con una funcionalidad personalizada y que podían hacerse más fluidos, rápidos y fáciles de usar.
Nota: si no sabe qué es una biblioteca PJAX, le sugerimos que consulte MoOx/pjax ; En resumen, PJAX permite transiciones fluidas entre páginas mediante solicitudes de recuperación y cambio de elementos DOM.
Con el tiempo, mi intención cambió y comencé a notar con qué frecuencia los sitios de awwwards.com usaban PJAX, pero a menudo destrozaban la experiencia natural del sitio y el navegador. Muchos de los sitios parecían interesantes a primera vista, pero el uso real a menudo contaba una historia diferente: las barras de desplazamiento a menudo se anulaban, la búsqueda previa era a menudo demasiado apresurada y faltaba preparación para personas sin potentes conexiones a Internet, CPU. y/o GPU. Entonces, decidí mejorar progresivamente la biblioteca que iba a construir. Comencé lo que llama la “iniciativa nativa” almacenada en el repositorio de GitHub okikio/native ; un medio para introducir todas las características interesantes y modernas de una manera liviana, compatible y de alto rendimiento.
Para la iniciativa nativa diseñó la biblioteca PJAX @okikio/native ; Mientras probaba en un proyecto real, me encontré con la API de animación web y me di cuenta de que no había bibliotecas que la aprovecharan, así que desarrolló @okikio/animate para crear una biblioteca de animación compatible con el navegador. ( Nota : esto fue en 2020, aproximadamente al mismo tiempo que se desarrolló use-web-animations de wellyshen. Si está usando reaccionar y necesita algunos efectos rápidos tipo animate.css, use-web-animations es una buena opción). Al principio, se suponía que era un contenedor simple pero, poco a poco, lo construí y ahora tiene una paridad de funciones del 80% con bibliotecas de animación más maduras.
Nota: puede leer más sobre la iniciativa nativa, así como sobre la biblioteca @okikio/native en el repositorio de Github okikio/native. Además, okikio/native es un monorepo con @okikio/native y @okikio/animate como subpaquetes dentro de él.
Dónde encaja @okikio/animate en este artículo
La API de animación web tiene un diseño muy abierto. Es funcional por sí sola, pero no es la API más intuitiva ni fácil de usar para los desarrolladores, por lo que desarrolló @okikio/animate para que actúe como un contenedor alrededor de WAAPI e introduzca las funciones que conoce y ama de otras bibliotecas de animación más madura (con algunas nuevas características incluidas) a la naturaleza de alto rendimiento de la API de animación web. Lea el archivo README del proyecto para obtener mucho más contexto.
Ahora comenzamos
@okikio/animate crea animaciones mediante la creación de nuevas instancias de Animate (una clase que actúa como contenedor de la API de animación web).
import { Animate } from"@okikio/animate";new Animate({ target: [/* ... */], duration: 2000, // ... });
La Animate
clase recibe un conjunto de objetivos para animar, luego crea una lista de instancias de animación WAAPI, junto con una animación principal (la animación principal es una pequeña instancia de animación que está configurada para animarse sobre un elemento no visible, existe como una forma de rastrear el progreso de las animaciones de los distintos elementos de destino), la Animate
clase luego reproduce cada instancia de animación de los elementos de destino, incluida la animación principal, para crear animaciones fluidas.
La animación principal está ahí para garantizar la precisión en las implementaciones de WAAPI de diferentes proveedores de navegadores. La animación principal se almacena en Animate.prototype.mainAnimation
, mientras que las instancias de animación del elemento de destino se almacenan en WeakMap
, siendo la clave su KeyframeEffect
. Puede acceder a la animación de un objetivo específico utilizando el archivo Animate.prototype.getAnimation(el)
.
No es necesario que comprendas completamente las oraciones anteriores, pero te ayudará a comprender lo que hace @okikio/animate. Si desea obtener más información sobre cómo funciona WAAPI, consulte MDN, o si desea obtener más información sobre la biblioteca @okikio/animate, le sugerimos que consulte el proyecto okikio/native en GitHub.
Uso, ejemplos y demostraciones.
De forma predeterminada, crear una nueva instancia de Animate es muy molesta, por eso creé la animate
función, que crea nuevas instancias de Animate cada vez que se llama.
import animate from "@okikio/animate";// orimport { animate } from "@okikio/animate";animate({ target: [/* ... */], duration: 2000, // ... });
Cuando utilices la biblioteca @okikio/animate para crear animaciones, puedes hacer esto:
import animate from "@okikio/animate";// Do this if you installed it via the script tag: const { animate } = window.animate;(async () = { let [options] = await animate({ target: ".div", // Units are added automatically for transform CSS properties translateX: [0, 300], duration: 2000, // In milliseconds speed: 2, }); console.log("The Animation is done...");})();
También puedes jugar con una demostración con controles de reproducción:
Ruta de movimiento de Pruebe:
Pruebe diferentes tipos de movimiento cambiando las opciones de animación:
También crearé una página de demostración compleja con polyfills:
Ver demostración
Puede encontrar el código fuente de esta demostración en los archivos animate.ts
y animate.pug
en el repositorio de GitHub. Y sí, la demostración usa Pug y es una configuración bastante compleja. Recomiendo encarecidamente consultar el archivo README como guía para empezar.
La iniciativa nativa usa Gitpod, por lo que si quieres jugar con la demostración, te recomiendo hacer clic en el enlace “Abrir en Gitpod”, ya que todo el entorno ya está configurado para ti: no hay nada que configurar.
También puedes consultar algunos ejemplos más en esta colección de CodePen que preparé. En su mayor parte, puedes transferir tu código de animejs a @okikio/animate con pocos o ningún problema.
Probablemente debería mencionar que @okikio/animate admite las palabras clave target
y targets
para configurar los objetivos de animación. @okikio/animate fusionará ambas listas de objetivos en una sola y usará Set
s para eliminar cualquier objetivo repetido. @okikio/animate admite funciones como opciones de animación, por lo que puedes usar asombrosos similares a animejs. ( Nota : el orden de los argumentos es diferente; lea más en la sección "Opciones de animación Propiedades CSS como métodos" del archivo README).
Restricciones y limitaciones
@okikio/animate no es perfecto; En realidad, nada lo es, y dado que la API de animación web es un estándar de vida que se mejora constantemente, @okikio/animate todavía tiene mucho espacio para crecer. Dicho esto, estoy constantemente tratando de mejorarlo y me encantaría recibir sus comentarios, así que abra una nueva edición, cree una solicitud de extracción o podemos tener una discusión en el proyecto GitHub.
La primera limitación es que en realidad no tiene una línea de tiempo incorporada. Hay algunas razones para esto:
- Se me acabó el tiempo. Todavía soy sólo un estudiante y no tengo mucho tiempo para desarrollar todos los proyectos que quiero.
- No pensé que fuera necesaria una línea de tiempo formal, ya que se admitía la programación asíncrona/en espera. Además, lo agregué
timelineOffset
como una opción de animación, en caso de que alguien alguna vez necesite crear algo similar a la línea de tiempo en animejs. - Quería que @okikio/animate fuera lo más pequeño posible.
- Dado que los efectos de grupo y de secuencia estarán disponibles próximamente, pensé que sería mejor dejar el paquete pequeño hasta que surja una necesidad real. En ese sentido, recomiendo leer la serie de Daniel C. Wilson sobre WAAPI, particularmente la cuarta entrega que cubre efectos de grupo y efectos de secuencia.
Otra limitación de @okikio/animate es que carece de soporte para flexibilizaciones personalizadas, como resortes, elásticos, etc. Pero consulte la propuesta de Jake Archibald para un worklet de flexibilización. Analiza múltiples estándares que están actualmente en discusión. Prefiero su propuesta, ya que es la más fácil de implementar, sin mencionar la más elegante del grupo. Mientras tanto, me estoy inspirando en el artículo de Kirill Vasiltsov sobre animaciones de Spring con WAAPI y planeo crear algo similar en la biblioteca.
La última limitación es que @okikio/animate solo admite unidades automáticas en funciones de transformación, por ejemplo Este ya no es el caso a partir de @okikio/animate@2.2.0, pero todavía existen algunas limitaciones en las propiedades CSS que color de soporte. Consulte la versión de GitHub para obtener más detalles.translateX
, translate
, scale
, skew
, etc.
Por ejemplo:
animate({ targets: [".div", document.querySelectorAll(".el")], // By default "px", will be applied translateX: 300, left: 500, margin: "56 70 8em 70%", // "deg" will be applied to rotate instead of px rotate: 120, // No units will be auto applied color: "rgb(25, 25, 25)", "text-shadow": "25px 5px 15px rgb(25, 25, 25)"});
Mirando hacia el futuro
Algunas funciones futuras, como ScrollTimeline, están a la vuelta de la esquina. No creo que nadie sepa realmente cuándo se lanzará, pero desde ScrollTimeline en Chrome Canary 92, creo que es seguro decir que las posibilidades de un lanzamiento en el futuro cercano parecen bastante buenas.
Construí la opción de animación de la línea de tiempo en @okikio/animate para prepararla para el futuro. He aquí un ejemplo:
¡Gracias a Bramus por la inspiración para la demostración! Además, es posible que necesite la versión Canary de Chrome o activar las funciones de la plataforma web experimental en Chrome Flags para ver esta demostración. Sin embargo, parece funcionar bien en Firefox, así que...
Si desea leer más sobre ScrollTimeline, Bramus escribió un excelente artículo al respecto. También sugeriría leer el artículo de Google Developers sobre Animation Worklets.
Mi esperanza es hacer la biblioteca más pequeña. Actualmente tiene ~5,79 KB, lo que parece alto, al menos para mí. Normalmente, usaría una inserción de Bundlephobia, pero tiene problemas para agrupar el proyecto, por lo que si desea verificar el tamaño, le sugiero usar Bundle.js.org porque en realidad agrupa el código localmente en su navegador. Lo construí específicamente para verificar el tamaño del paquete de @okikio/animate, pero tenga en cuenta que no es tan preciso como bundlephobia.
Polirellenos
Una de las demostraciones anteriores muestra polyfills en acción. Necesitará web-animations-next.min.js
web-animations-js para admitir líneas de tiempo. Otras características modernas KeyframeEffect
son requeridas por el constructor.
Polyfill usa JavaScript para probar si KeyframeEffect
es compatible y, si no lo es, se carga y hace lo suyo. Simplemente evite agregar async/defer al polyfill, o no funcionará de la manera esperada. También querrás rellenar Map
, Set
y Promise
.
html head !-- Async -- script src="https://cdn.polyfill.io/v3/polyfill.min.js?features=default,es2015,es2018,Array.prototype.includes,Map,Set,Promise" async/script !-- NO Async/Defer -- script src="./js/webanimation-polyfill.min.js"/script /head body !-- Content -- /body/html
Y si está compilando para ES6+, le recomiendo encarecidamente usar esbuild para transpilar, agrupar y minimizar. Para ES5, sugiero usar esbuild (con minify desactivado), Typecript (con objetivo de ES5) y terser; A partir de ahora, esta es la configuración más rápida para transpilar a ES5, es más rápida y confiable que Babel. Consulte el Gulpfile de la demostración para obtener más detalles.
Conclusión
@okikio/animate es un contenedor de la API de animación web (WAAPI) que te permite utilizar todas las funciones que te gustan de animejs y otras bibliotecas de animación, en un paquete pequeño y conciso. Entonces, ¿qué piensas después de leer sobre esto? ¿Es algo que crees que utilizarás cuando necesites crear animaciones complejas? O, aún más importante, ¿hay algo que le impediría usarlo? Deje un comentario a continuación o únase a la discusión en Github Discussions.
Este artículo apareció originalmente en dev.to, también apareció en hackernoon.com y en mi blog blog.okikio.dev.
Foto de Pankaj Patel en Unsplash.
Deja un comentario