viernes, 21 de septiembre de 2018

Truco AnimeJS: como cambiar propiedades al vuelo

Esta semana una compañera y yo hemos tenido que lidiar con una animación. El caso es que la animación tiene bastantes componentes y mi compañera pensó en usar AnimeJS para facilitar nuestro trabajo. AnimeJS es una librería que es bastante sencilla de entender y de forma rápida se consiguen hacer animaciones complejas, que de otro modo llevarían muchas horas en la elaboración de las hojas de estilo, de funciones javascript u otras técnicas que se puedan emplear. 

Para ilustrar lo que quiero exponer veamos la siguiente animación en acción: 


Una de las características de esta página es que el usuario pueda cambiar la velocidad a la que suceden las animaciones de los distintos elementos. Es decir, que puede acelerar o frenar el ritmo al que salen, entran, crecen, etc. los textos y figuras que aparecen en la pantalla.

Vamos con el código. Aquí vemos el código Javascript de la página:

1 var valorDelay = 30; 
2 var progress = document.querySelector('.progress'); 

4 var animacion = anime.timeline({ 
5     loop: true, 
6 }); 

8 anima(valorDelay), 

10 progress.addEventListener('input', function() 
11         { valorDelay= 30 - progress.value;
12           animacion.pause(); 
13           animacion=undefined; 
14           animacion = anime.timeline({loop: true,}); 
15           anima(valorDelay);}); 
16 
17 function anima(valorDelay){ 
18 
19 animacion 
20   .add({ 
21      targets: '.cabecera', 
22      translateY: [-500, 0], 
23      opacity:[0,1], 
24      delay: function(target,index) {return valorDelay * index; }, 
25   }) 
26   .add({ 
27      targets: '.cuadro', 
28      scale: [0, 1], 
29      delay: function(target,index) {return valorDelay * ((index + 1) * 50);}, 
30   }) 
31   .add({ 
32      targets: '.barra', 
33      width: [0, 1750], 
34      delay: function(target,index) {return valorDelay * ((index + 1) * 50);}, 
35   }) 
36   .add({ 
37      targets: '.texto', 
38      opacity:[0,1], 
39      translateX: [0, 80], 
40      delay: function(target,index) {return valorDelay * ((index + 1) * 50);}, 
41 
42   }) ;
43 }

La animación tiene un “timeLine” que maneja los elementos de la página en 4 "ordenes" de animación, que se corresponden con los .add, que hay en las líneas 20, 26, 31 y 36. 

La página está preparada para aumentar o disminuir el tiempo de retardo entre animaciones con un botón que recorre una barra creada con la etiqueta “” de html. Con el objetivo de cambiar el valor de la propiedad “delay”, se ha empleado la técnica de incluir la instanciación de la animación en una función que recibe como parámetro el valor de retardo a aplicar. 

Cuando desde la página se solicita aumentar o disminuir la velocidad de la animación, se captura con el método “addEventListener”. Cuando se maneja el botón del elemento “” se dispara este método y se asigna a “delay” un valor en función de la posición en que esté el botón. El valor de “” puede ir de 0 a 30 de 10 en 10. Cuando está a cero la animación debe ir despacio, cuando está a 30 más rápido. Es decir, el valor de “” es inversamente proporcional al del retraso requerido.Por este motivo se calcula el  valor de “delay” de forma inversa respecto a   ”, es decir cuánto más grande es “” más pequeño es “delay”.

En este ejemplo se usa un algoritmo de animación aprovechando las funcionalidades de AnimeJS con la particularidad de que dinámicamente se requiere que cambie el valor de una propiedad de la animación, en este caso el tiempo de retardo entre una animación y otra. 

El problema

Cuando se requiere cambiar el valor de “delay” se llama a la función “anima(valorDelay)” con el valor de retardo como parámetro. Sin embargo, hay que tener en cuenta que cada vez que se invoca la función “anima(valorDelay),” se está creando una nueva instancia de la animación. Esto provoca que habiendo varias animaciones activas, la animación empiece a hacer cosas raras si esperamos un poco. Este asunto es lo que me ha animado a escribir este post, por un lado exponer el problema y por otro ofrecer una posible solución.

La solución

Lo que consigue que la animación no haga cosas raras son las sentencias 12, 13 y 14. Estas sentencias cierran la animación que está en marcha, desconectan esta instancia del navegador y abren otra instancia de animación. Así la animación comienza y funciona perfectamente.


Esperamos Maria ( https://www.domestika.org/en/mariadelamareria ) y yo que os sea de utilidad nuestra experiencia. Si necesitáis algo, dejadnos un comentario.

No hay comentarios:

Publicar un comentario