Animaciones con JS

Rate this content
Bookmark

Creando diferentes efectos de animación como rebotes, escritura con javascript puro. Observando varios enfoques para crear animaciones con funciones basadas en el tiempo y Request Animation Frame.

19 min
16 Jun, 2022

Video Summary and Transcription

La charla de hoy trata sobre animaciones en Javascript, abarcando las tasas de fotogramas y diferentes métodos como transiciones y animaciones CSS. JavaScript proporciona un mayor control sobre las animaciones, permitiendo la interpolación y simulación de escenarios del mundo real. Se discuten diferentes enfoques para animar una caja de cero a 100 píxeles, incluyendo bucles for, temporizadores y la API de animaciones web. Se destaca Request Animation Frame como una solución para animaciones consistentes y suaves. La API de Animaciones Web se presenta como una herramienta poderosa junto con las animaciones y transiciones CSS, aunque tiene un soporte limitado en los navegadores.

Available in English

1. Introducción a las animaciones en Javascript

Short description:

La charla de hoy trata sobre las animaciones en Javascript. Discutiremos las tasas de fotogramas y cómo afectan la suavidad de la animación. Se pueden utilizar diferentes métodos como las transiciones y animaciones CSS para lograr animaciones web.

¿Cómo les va hasta ahora? ¿Están disfrutando de la charla? Genial. ¿Hay desarrolladores de backend aquí? ¿Haciendo ruido? ¿Alguno diseñador de movimiento? Ok, nadie.

Hoy mi tema es animations. Animations en palabras simples es simplemente una forma de comunicar movimiento. Si bien este concepto se introdujo primero en las películas antes de ser llevado al web, pero las personas han estado tratando de encontrar formas de comunicar movimiento desde hace mucho tiempo. ¿Cuántos de ustedes recuerdan este libro de dibujos animados, donde dibujábamos un montón de dibujos y los pasábamos rápidamente para crear una percepción de movimiento?

La idea es que cuando las imágenes se muestran lo suficientemente rápido, nuestro cerebro pierde la capacidad de ver los fotogramas individuales y los mezcla en una sola imagen en movimiento. Pero en el mundo digital, tenemos fotogramas. Cada fotograma tiene un dibujo y la idea es similar al libro de dibujos animados, simplemente se colocan esos fotogramas juntos muy rápido para crear la percepción de movimiento.

Hola, mi nombre es Ashima. Soy una amiga e ingeniera en Miro, y hoy voy a hablar especialmente sobre animations en Javascript. Todos ustedes deben haber escuchado este término, tasas de fotogramas, fotogramas por segundo. Lo escuché por primera vez en las películas. La tasa de fotogramas es el número de fotogramas mostrados en un segundo. Entonces, si mostramos 60 fotogramas en un segundo, se convierte en 60 fotogramas por segundo, y cuanto más fotogramas mostremos en un segundo, más suave será la animación. Para renderizar animaciones suaves en la web, apuntamos a 60 fotogramas por segundo. Pero eso depende mucho del dispositivo que estés usando. Por ejemplo, si estás usando un teléfono móvil, es muy probable que funcione a una frecuencia inferior a 60 hercios. Entonces, la tasa de fotogramas sería de 30 fotogramas por segundo o la que admita el dispositivo.

En la web, podemos lograr animations usando JavaScript, usando CSS, usando transiciones y animaciones CSS. En las transiciones CSS, generalmente defines dos puntos. Uno es el punto de inicio y el otro es el punto final. Lo que sucede en el medio es controlado por el navegador. Esto es lo que llamamos interpolación. En las transiciones CSS, generalmente necesitas una acción para activarlas. Por ejemplo, puedes usar un hover o un click. Y no puedes ejecutarlas en bucle. Entonces tenemos las CSS animations. Y en las CSS animations, también puedes definir puntos intermedios utilizando keyframes, además de definir el punto de inicio y el punto final. Y sí, la interpolación, nuevamente, es controlada por el navegador.

2. Controlling Animations in JavaScript

Short description:

A veces CSS no es suficiente para lograr las animaciones deseadas en JavaScript. JavaScript proporciona un mayor control sobre las animaciones, permitiendo la interpolación y simulación de escenarios del mundo real. Existen diferentes enfoques para animar una caja de cero a 100 píxeles, incluyendo el uso de un bucle for, temporizadores como setInterval y setTimeout, el requestAnimationFrame y la moderna API de animaciones web. Al utilizar un bucle for, el navegador renderiza la caja directamente en 100 píxeles en lugar de actualizar incrementalmente su posición debido a cómo funciona el bucle de eventos. Los temporizadores como setInterval y setTimeout se pueden utilizar para resolver este problema ejecutando una devolución de llamada después de un retraso especificado.

Así es como se movería entre diferentes estados. Pero a veces no es posible hacer todo con CSS. Sé que el navegador hace mucho por nosotros cuando se trata de animaciones. Pero cuando necesitamos más control sobre las animaciones, necesitamos usar JavaScript. Y así, JavaScript te permite controlar la interpolación y simular escenarios del mundo real.

Por ejemplo, la caída libre de un objeto o la caída de nieve. Supongamos que se te presenta este problema, que quieres animar una caja de cero a 100 píxeles. ¿Cuántos de ustedes han encontrado esto en sus entrevistas? Yo sí. Y fracasé. Pero hoy veremos que hay un par de enfoques para resolver esto, básicamente. Puedes usar un bucle for si eres nuevo en JavaScript. También puedes usar temporizadores, setInterval, setTimeout. También puedes usar el requestAnimationFrame y luego la moderna API de animaciones web.

Si estás usando un bucle for, puedes ejecutarlo desde cero hasta 100 píxeles y decirle a tu navegador: `ok, navegador, muéstrame esto en una posición específica`. Pero esto no funciona. Lo que sucede en este caso es que la caja se renderiza directamente en 100 píxeles. Pero eso no es lo que quieres. Quieres actualizar la posición incrementalmente. La expectativa es que el navegador haga algo como esto, mostrarlo en 0, 1, 2 y luego en 100. Pero la realidad es que la línea se ejecuta como translateX 100 píxeles. Maldito navegador. Esto se debe a cómo funciona el bucle de eventos. Me gusta mucho este diagrama de Jake. Si no has visto la charla sobre el bucle de eventos, realmente debes verla. Lo que sucede aquí es que el bucle for se ejecuta como una tarea. Y después de que se ejecuta todo el bucle for, el navegador calcula los estilos, renderiza el diseño y luego realiza la pintura. Y por eso vemos que solo se ejecuta translateX 100 píxeles.

Otra forma de resolver este problema es utilizando temporizadores. Puedes usar setInterval y setTimeout. Ambas funciones toman una devolución de llamada y un tiempo de retraso después del cual se ejecutará la devolución de llamada.

3. Controlando Animaciones en JavaScript (Parte 2)

Short description:

Para lograr una animación fluida, debemos apuntar a 60 fotogramas por segundo. El tiempo de retardo para set interval y set timeout debe ser de aproximadamente 16 milisegundos por fotograma. Sin embargo, set interval no garantiza el intervalo de ejecución si una función tarda más que el tiempo especificado. Set timeout se puede utilizar en recursión para asegurar el tiempo de ejecución adecuado. Ambos temporizadores tienen problemas con la sincronización inconsistente y la falta de sincronización con el navegador. Además, set interval sigue ejecutándose incluso si la pestaña está inactiva, consumiendo más CPU y batería. Para solucionar estos problemas, podemos utilizar request animation frame.

Entonces, ¿cuál debería ser el tiempo de retardo aquí? Definitivamente, quieres renderizar una animación fluida. Para eso, hemos discutido que queremos apuntar a 60 fotogramas por segundo. Si se deben renderizar 60 fotogramas en 1,000 milisegundos, entonces un fotograma debería renderizarse en casi 16 milisegundos. Este será el temporizador tanto para set interval como para set timeout.

Aquí creemos una función llamada animate. Dentro de set interval, puedes actualizar la posición en 1. Por supuesto, no quieres que el intervalo se ejecute infinitamente, así que puedes borrar el intervalo cuando la caja alcance los 100 píxeles. Después de eso, el navegador lo renderizará en la posición específica. Esto funciona bien. Si lo ejecutas, se ejecuta perfectamente una animación fluida. Pero el problema con set interval ocurre cuando la función dentro de set interval tarda más que el tiempo especificado. Supongamos que teníamos tres funciones aquí, ¿verdad? Y cada una debe ejecutarse a intervalos de 16 milisegundos. Pero si la función 1 tarda más de 16 milisegundos, supongamos que tarda como 50 milisegundos, las otras dos funciones se llamarían instantáneamente en un orden inesperado. Set interval no garantiza el intervalo de ejecución.

También puedes abordar este problema utilizando set timeout. En lugar de ejecutar un bucle interno, en lugar de usar set interval, puedes usar set timeout en recursión. Básicamente, aquí estamos comprobando si la posición es menor que 100, llamaremos a la función animate nuevamente en el set timeout. Esto funciona muy bien y también garantiza que nuestro método se ejecute por completo hasta que la función se esté ejecutando. La siguiente función nunca se enviará para su ejecución. Se mantiene la diferencia de tiempo entre la ejecución de dos funciones. Pero todavía hay algunos problemas con ambos temporizadores. En primer lugar, el retardo que se proporciona en el segundo argumento puede ser más largo de lo previsto. Puede haber una sincronización inconsistente entre los fotogramas. Además, estos métodos no están sincronizados con el navegador. Set interval, set timeout, no tienen idea de lo que está sucediendo en la pantalla. El navegador tiene que hacer la animación y luego volver a pintar toda la pantalla, lo cual requiere mucho más cálculo. Además, si usas set interval, las animaciones siguen ejecutándose incluso si la pestaña está inactiva. Esto consume más CPU y batería. Para solucionar todos estos problemas, existe request animation frame.

4. Request Animation Frame y Consistencia

Short description:

Request animation frame se sincroniza con el navegador, se ajusta automáticamente a la frecuencia de actualización del dispositivo y ahorra uso de CPU y vida de la batería. Al incrementar la posición basada en el tiempo, las animaciones pueden ser consistentes y fluidas en todos los dispositivos.

Entonces, ¿alguien sabe cuántos de ustedes están familiarizados con esto? Bien. Casi todos han escuchado. Entonces, request animation frame le dice al navegador que quieres realizar una animación. Y le pregunta al navegador, ¿puedes hacer esta animación por mí cuando vayas a renderizar la pantalla, cuando vayas a pintar? El navegador dice, sí, claro. Lo haré, ejecutaré esta función por ti cada vez que vaya a pintar la próxima vez.

Entonces, request animation frame toma un callback. Como su ejecución está controlada por el navegador, no es necesario proporcionar ningún temporizador, ningún tiempo de retardo. Aquí es donde request animation frame está en el bucle de eventos. En algunos navegadores, está aquí, como, arriba de los estilos. Pero en otros está aquí. Pero la idea principal es que la función dentro de RAF se ejecuta cuando el navegador va a pintar la pantalla.

El beneficio es que está sincronizado con el navegador. Y también se ajusta automáticamente según la frecuencia de actualización del dispositivo. Entonces, si estás ejecutando estas animations incluso en tu teléfono móvil, el RAF se ajustará automáticamente a la frecuencia de fotogramas del teléfono móvil. Además, cuando la pestaña está inactiva, las animations no se ejecutan. Esto ahorra mucho uso de CPU y vida de la batería. Ahora, si tenemos que reescribir esta función utilizando el animation frame, simplemente puedes cambiar el set timeout por el animation frame. Y esto sería una animación fluida. Pero puedes ver que todavía hay algún problema.

Lo que está sucediendo aquí ahora mismo es que esta animación se está ejecutando a diferentes velocidades en diferentes dispositivos. Porque el request animation frame se ejecutará a 60 fotogramas por segundo en un navegador. Pero en un teléfono móvil, estará limitado a 30 fotogramas por segundo. Entonces, en tu navegador, la animación será dos veces más rápida. Pero definitivamente no quieres eso. Quieres que tus animations sean consistentes y fluidas en todos los dispositivos. Entonces, aquí la idea es que en lugar de incrementar la posición en uno, puedes pensar en incrementar la posición basada en el tiempo que ha pasado. Así que puedes calcular aquí cuánto tiempo ha pasado y cuál debería ser la posición de la caja en ese momento específico. Entonces podemos pasar una distancia y una duración e incrementar la posición basada en el tiempo. Ahora esto se ejecutará sin problemas en todos los dispositivos. Hemos logrado una animación fluida y consistente en todos los dispositivos.

5. Optimización de Animaciones y Web Animations API

Short description:

Para optimizar aún más las animaciones, transfiera los cálculos a un hilo de trabajo. Request Animation Frame es poderoso pero tiene inconvenientes. Web Animations API es una herramienta poderosa inspirada en las animaciones y transiciones de CSS.

Pero ¿todavía se puede optimizar aún más? Si ves, hay dos cosas que estamos haciendo aquí. Estamos haciendo los cálculos y estamos haciendo el dibujo. Y ambos se ejecutan en el hilo principal. Entonces, lo que se está haciendo es calcular la posición. La función de dibujo, por lo que lo que queremos hacer es colocar la función de dibujo en el request animation frame. Entonces, la responsabilidad de request animation frame debería ser solo pintar. Y lo que puedes hacer es transferir los cálculos al hilo de trabajo.

Todos sabemos que los hilos de trabajo se ejecutan en paralelo. Entonces, en lugar de hacer los cálculos en el hilo principal, puedes transferirlos a un hilo de trabajo. Así es como se ve nuestra función de cálculo de posición. Simplemente estamos usando setInterval. En setInterval, puedes actualizar la posición y borrar el intervalo cuando la caja alcance los 100 píxeles. Ahora, en lugar de calcular la posición, puedes transferirlo al hilo de trabajo. Entonces, en lugar de llamar a calculate position, aquí puedes llamar a calculate position en el hilo de trabajo. Y en el hilo de trabajo, puedes hacer todos los mismos cálculos. El hilo de trabajo enviará al archivo principal la posición actualizada. Entonces, en main.js, aquí puedes obtener la posición actualizada y esta es la solución. Entonces, lo que has hecho es transferir los cálculos al hilo de trabajo. Entonces, nuestro hilo principal está libre para realizar cualquier otra acción del usuario.

Si bien request animation frame es muy poderoso y nos ayuda a lograr animaciones más suaves y de mejor rendimiento. Pero aún hay algunas desventajas porque request animation frame se ejecuta en el hilo principal, ¿verdad? Y si el hilo principal está ocupado y el navegador tarda más tiempo en pintar las animaciones, entonces aún tendremos dificultades para tener estas animaciones suaves. Es como conducir un Ferrari en la Autobahn, pero si te quedas atrapado en un atasco de tráfico, no hay mucho que puedas hacer. Y además, request animation frame está limitado a 60 fotogramas por segundo en muchos dispositivos Apple, como el iPad Pro. Aunque si usas animaciones CSS allí, puede funcionar a 120 fotogramas por segundo.

Entonces, tenemos otra herramienta muy poderosa, que es la Web Animations API. Esto está muy inspirado en las animaciones y transiciones de CSS. Además, sintácticamente, es bastante similar a CSS. Pero el problema con CSS es que es declarativo. Entonces, cada vez que defines los keyframes, debes especificar todos los valores mientras escribes el CSS.

6. JavaScript Animations and Web Animations API

Short description:

JavaScript permite valores dinámicos para posiciones y duraciones en animaciones. Las animaciones web tienen una estructura similar a las animaciones CSS, con modelos de tiempo y animación. La API de animaciones web aprovecha la naturaleza dinámica de JavaScript y es una herramienta adicional junto con las transiciones y animaciones CSS. Se ejecuta en un hilo compuesto, proporcionando animaciones de alto rendimiento. Sin embargo, el soporte está limitado a Chrome, Safari y la última versión de Internet Explorer.

Pero con JavaScript, te permite establecer dinámicamente los valores desde posiciones hasta duraciones. Entonces, si tienes que animar esta caja usando CSS, escribirías algo como esto. Define la duración, la función de tiempo y define los keyframes. Las animaciones web tienen una estructura similar.

En las animaciones web, tienes el modelo de tiempo y el modelo de animación. En el modelo de tiempo, definirías duraciones, iteraciones, retraso, easing. Y en el modelo de animación, definirías los keyframes. Así es como se ve en el CSS. Y si estás usando las animaciones web, entonces los keyframes estarían dentro de un array. Este objeto se parece a un keyframe, excepto por el hecho de que no estamos definiendo el porcentaje aquí.

Entonces, la solución con el request animation frame, perdón, la API de animaciones web se vería algo como esto. Aquí puedes aprovechar la naturaleza dinámica de JavaScript. Entonces, lo que puedes hacer es que la distancia y la duración se pasen a la función y puedes establecer dinámicamente la distancia. Así que diría que tenemos muchas herramientas poderosas para lograr animaciones en JavaScript. Tenemos el request animation frame. También tenemos las transiciones y animaciones CSS. Y todas ellas son realmente poderosas. Y la API de animaciones web no es algo que las reemplace, sino que es una herramienta adicional. Así que usa la que mejor se adapte a tus necesidades. La API de animaciones web también se ejecuta en un hilo compuesto, por lo que no se ejecuta en el hilo principal. Es por eso que puedes lograr animaciones muy eficientes con la API de animaciones web. Sin embargo, el soporte aún es limitado. Está en Chrome y la última versión de Safari e Internet. Pero en los navegadores antiguos, aún no está soportado.

Muchas gracias. Y eso es todo lo que tenemos en términos de animaciones JavaScript. Debería conseguir un asiento en la parte delantera. Eso sería mucho mejor. A pesar de algunos problemas técnicos, lo logramos. Sí.

QnA

Q&A sobre Animaciones y Pruebas

Short description:

Felicitaciones por la maravillosa charla. Si tienen alguna pregunta, por favor háganla usando Slido. Las animaciones se pueden compartir más tarde y se puede encontrar un enlace en el perfil de Twitter del orador. Probar las animaciones puede ser desafiante, pero el uso de personalización y bibliotecas puede ayudar. Las animaciones CSS son preferibles para animaciones simples, mientras que las animaciones JavaScript ofrecen más control e interpolación.

Felicitaciones. Esa fue una maravillosa charla. Me pregunto, solo porque no tenemos una pregunta en este momento, por eso esta diapositiva está aquí. Personas, por favor hagan sus preguntas usando Slido.

Me pregunto, ¿tienes un sitio de portafolio en algún lugar donde podamos ver las animaciones que has hecho? Las animaciones, no las he subido a GitHub en este momento. Pero sí, puedo compartirlas más tarde. Sí, eso sería genial. Creo que todos han visto tu perfil de Twitter, así que puedes compartir el enlace allí. Sí, claro, seguro. Eso sería muy divertido.

Una pregunta que responderé es ¿cómo pruebas con animaciones? Estamos acostumbrados a simplemente desactivarlas en las pruebas, pero eso introduce errores en nuestras animaciones y pasan desapercibidos, ¿verdad? Sí, eso depende del enfoque que estés utilizando. Si estás utilizando setInterval o estás utilizando requestAnimationFrame. Sé que hay un par de problemas con el marco de pruebas, y como estamos usando los temporizadores, también es difícil probarlo. Pero hasta ahora lo que hago es usar alguna personalización, algunas bibliotecas para hacer las pruebas. Genial, muchas gracias.

Oh, tenemos otra pregunta que llega. Justo a tiempo. ¿En qué escenarios recurres a las animaciones CSS, y en cuáles deberías usar las animaciones JavaScript en su lugar? Entonces, si sabes que la animación va a ser simple y no quieres mucho control sobre las animaciones, siempre prefiere las animaciones CSS. Porque es más eficiente. Pero si necesitas más control, como te mencioné la interpolación, si quieres controlar esos valores también, que no puedes definir en los keyframes de CSS, entonces es mejor usar JavaScript. Genial. Muchas gracias, y muchas gracias nuevamente por tu charla. Gracias. Demos un gran aplauso a todos.

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

JSNation Live 2021JSNation Live 2021
33 min
Keep Scrolling
Wait! Not so fast - Stop scrolling and hang out with me for a while! When done right, scroll based animations can add polish to a site, and make online storytelling feel more immersive. GreenSock's ScrollTrigger enables you to achieve buttery smooth scroll based animations with minimal code. Let's dig in to some of it's features together.
Vue.js London Live 2021Vue.js London Live 2021
32 min
Animation and Vue.js
There's a lot to gain from adding animations to your site or app. Beyond their visual appeal, you can guide the user's attention, cover up slow to load components and elements, and reveal sections of a page without the user wondering where it came from. This talk will cover the built-in ways Vue.js helps you animate your site, and how for more complicated animations you can hook into third party libraries. It'll also cover the basics of animation itself – what to animate, what not to animate – and how you can use animations to enhance your website without harming the experience of people with disabilities.
React Summit Remote Edition 2021React Summit Remote Edition 2021
35 min
Lessons Learnt from Building Interactive React Applications
When users directly manipulate onscreen objects instead of using separate controls to manipulate them, they’re more engaged and more readily understand the results of their actions. Subtle animations can give people meaningful feedback to help clarify the result of their actions. But, the devil is in the details. What often seems simple can be complex to get right, especially when you care about accessibility. Sid shares the lessons he has learned building interactive UIs.

Workshops on related topic

JS GameDev Summit 2022JS GameDev Summit 2022
165 min
How to make amazing generative art with simple JavaScript code
Top Content
WorkshopFree
Instead of manually drawing each image like traditional art, generative artists write programs that are capable of producing a variety of results. In this workshop you will learn how to create incredible generative art using only a web browser and text editor. Starting with basic concepts and building towards advanced theory, we will cover everything you need to know.