Animación de JavaScript que funciona (Parte 2 de 4)

En el último post, presentamos la idea de spriting, Una forma fácil de animar en JavaScript que funciona en todos los navegadores. También aprendimos cómo configurar el sprite como imagen de fondo para un div y luego use una línea de JavaScript para cambiar la posición del fondo para que aparezca como si la imagen se hubiera movido.

En esta publicación, usaremos esta técnica para animar los movimientos de correr y saltar. Para crear la animación, necesitaremos cambiar rápidamente la posición del fondo en un intervalo regular. Vuelve a echar un vistazo al sprite que estamos usando..


Conoce a J, la mascota de mi empresa, Joust Multimedia..

En nuestro ejemplo, tenemos diez imágenes en total: una de J de pie mirando hacia la derecha, tres de J corriendo hacia la derecha y una de J saltando hacia la derecha (con el mismo número de cada cuadro mirando hacia la izquierda). Vamos a empezar con hacerlo correr hacia la derecha. Para hacer que nuestra imagen parezca que se está ejecutando, tendremos que hacer dos cosas: cambiar el sprite a una imagen diferente y mover el div hacia la derecha.


Corriendo hacia la animación correcta

Ciertamente, no queremos quedarnos atascados haciendo clic en diferentes botones para recorrer los sprites, así que tendremos que crear algunas funciones que lo hagan automáticamente..

Para nuestra función de ejecución, queremos:

  1. Mueve el div hacia la derecha ligeramente
  2. Pasar al siguiente cuadro de animación.
  3. Pausa por una fracción de segundo (para preservar la ilusión de "persistencia de la visión")
  4. Repetir la función de nuevo.

Afortunadamente, hay una manera fácil de hacer un bucle con las funciones. Un comando nativo en JavaScript llamado setTimeout nos permitirá crear un retraso temporizado, después del cual volveremos a llamar a la función (desde dentro de la función).

 function run_right () // Mover ligeramente a la derecha ... // Cambiar al siguiente cuadro de animación ... // esto llamará 'run_right' nuevamente después de 200 milisegundos setTimeout (function () run_right ();, 200); 

Así que ahora tenemos una función que se llamará de nuevo cinco veces por segundo (que será lo suficientemente rápida para crear animación para nuestros propósitos). Recuerde que los navegadores no son muy precisos con sus temporizadores. Puede especificar el tiempo en milisegundos, pero eso no significa que su script se ejecutará en ese momento exactamente!

Nuestro siguiente problema es cómo nuestra función va a saber a qué sprite cambiar. En nuestro ejemplo, necesitaremos desplazarnos hacia adelante y hacia atrás a través de nuestras tres imágenes (para tener cuatro cuadros de animación en total). Para hacer esto, vamos a pasar a nuestra función un poco de información para decirle a qué diapositiva cambiar. Una vez en la función, haremos una prueba que comprobará en qué diapositiva debemos estar, luego cambiaremos la posición de fondo al sprite correcto. Cuando volvamos a llamar a la función, pasaremos la siguiente diapositiva como argumento.

 función run_right (deslizar) // Mover ligeramente a la derecha ... cambiar (deslizar) // esta instrucción de conmutación comprueba las diferentes posibilidades de 'diapositiva' caso 1: // si 'diapositiva' es igual a '1' ... document.getElementById ( 'j'). style.backgroundPosition = "-40px 0px"; setTimeout (function () run_right (2);, 200); descanso; caso 2: // si 'slide' es igual a '2'… document.getElementById ('j'). style.backgroundPosition = "-80px 0px"; setTimeout (function () run_right (3);, 200); descanso; caso 3: // si 'slide' es igual a '3' ... document.getElementById ('j'). style.backgroundPosition = "-120px 0px"; setTimeout (function () run_right (4);, 200); descanso; caso 4: // si 'slide' es igual a '4' ... document.getElementById ('j'). style.backgroundPosition = "-80px 0px"; setTimeout (function () run_right (1);, 200); descanso; 

Y ahora, cuando llamamos a la función por primera vez, debemos asegurarnos de que pasamos la diapositiva de inicio.

 

Del mismo modo, para mover nuestro div ligeramente a la derecha, podemos pasar el atributo inicial izquierdo de la div, luego mueve el div ligeramente cada vez que se llama la función.

 función run_right (diapositiva, izquierda) izquierda = izquierda + 15; // Incrementa su atributo izquierdo en 15px document.getElementById ('j'). Style.left = left + "px"; switch (slide) // esta instrucción de switch busca diferentes posibilidades para el caso de 'slide' 1: // si 'slide' es igual a '1'… document.getElementById ('j'). style.backgroundPosition = "-40px 0px" ; setTimeout (function () run_right (2, left);, 200); descanso; caso 2: // si 'slide' es igual a '2'… document.getElementById ('j'). style.backgroundPosition = "-80px 0px"; setTimeout (function () run_right (3, left);, 200); descanso; caso 3: // si 'slide' es igual a '3' ... document.getElementById ('j'). style.backgroundPosition = "-120px 0px"; setTimeout (function () run_right (4, left);, 200); descanso; caso 4: // si 'slide' es igual a '4' ... document.getElementById ('j'). style.backgroundPosition = "-80px 0px"; setTimeout (function () run_right (1, left);, 200); descanso; 

Y cuando inicialmente llamamos a la función, debemos asegurarnos de que pasamos la posición actual de la izquierda de nuestra div.

 

Deteniendo la animación

Entonces, ahora tenemos una función que, cuando se le llame, animará a J para que se ejecute a la derecha. Desafortunadamente, no tenemos manera de detenerlo. En primer lugar, tendremos que hacer que la función deje de llamarse a sí misma si J se ejecuta hasta el borde de nuestro escenario. Para hacer eso, cada vez que la función se ejecute, revisaremos un Si Declaración para ver si J tiene espacio para seguir corriendo. Si es así, ejecutaremos la función como normal. Si no, dejaremos de llamar a la función y lo devolveremos al sprite en pie..

 function run_right (deslizar, izquierda) // Si podemos agregar 15 píxeles a la izquierda y que el borde derecho de J no esté en el borde derecho del escenario ... si ((izquierda + 15) < (document.getElementById('stage').offsetWidth - document.getElementById('j').offsetWidth)) // We have room! Continue like normal here  else  // if we are on the right edge, we need to stop calling the function and return to standing document.getElementById('j').style.backgroundPosition = "0px 0px";  

Finalmente, desearemos tener una forma de detener la función, cuando sea necesario. Podemos configurar el setTimeout () comando a una variable, luego deténgalo con el clearTimeout () mando. Para hacer esto, necesitaremos declarar esa variable fuera de la función, de modo que podamos referirnos a ella más adelante. Por ahora, lo declararemos como una variable global. Esta es una práctica de codificación terrible, pero la corregiremos en la próxima publicación. Así es como se ve nuestra función.

 temporizador var función run_right (diapositiva, izquierda) si ((izquierda + 15) < (document.getElementById('stage').offsetWidth - document.getElementById('j').offsetWidth)) left = left + 15; // Increase his left attribute by 15px document.getElementById('j').style.left = left+"px"; switch (slide) // this switch statement checks for different possibilities for 'slide' case 1: // if 'slide' equals '1'… document.getElementById('j').style.backgroundPosition = "-40px 0px"; setTimeout(function()run_right(2, left);, 200); break; case 2: // if 'slide' equals '2'… document.getElementById('j').style.backgroundPosition = "-80px 0px"; setTimeout(function()run_right(3, left);, 200); break; case 3: // if 'slide' equals '3'… document.getElementById('j').style.backgroundPosition = "-120px 0px"; setTimeout(function()run_right(4, left);, 200); break; case 4: // if 'slide' equals '4'… document.getElementById('j').style.backgroundPosition = "-80px 0px"; setTimeout(function()run_right(1, left);, 200); break;   else  document.getElementById('j').style.backgroundPosition = "0px 0px";  

Y podemos crear otra función para detener el temporizador de ejecución y devolver el sprite a la imagen permanente.

 function stop_running () document.getElementById ('j'). style.backgroundPosition = "0px 0px"; clearTimeout (temporizador); 

Corriendo a la animación izquierda

Ahora tomando prestado el código de nuestro run_right función, podemos crear otra función para hacer una run_left Función, con solo unas pocas modificaciones..

 función run_left (stage, left) if ((left - 15)> 0) left = left - 15; document.getElementById ('j'). style.left = left + "px"; switch (stage) caso 1: document.getElementById ('j'). style.backgroundPosition = "-40px -50px"; timer = setTimeout (function () run_left (2, left);, 200); descanso; caso 2: document.getElementById ('j'). style.backgroundPosition = "-80px -50px"; timer = setTimeout (function () run_left (3, left);, 200); descanso; caso 3: document.getElementById ('j'). style.backgroundPosition = "-120px -50px"; timer = setTimeout (function () run_left (4, left);, 200); descanso; caso 4: document.getElementById ('j'). style.backgroundPosition = "-80px -50px"; timer = setTimeout (function () run_left (1, left);, 200); descanso;  else else document.getElementById ('j'). style.backgroundPosition = "0px -50px"; 

Animación de saltos

Finalmente, necesitamos crear una función de salto. Pasaremos dos argumentos a esta función, uno que rastreará si el div actualmente se está moviendo hacia arriba o hacia abajo y otro que rastreará el atributo superior actual de la div. Entre los dos, determinaremos en qué dirección div necesita moverse a continuación, y a qué distancia (vamos a mover el div menos distancia cerca del arco del salto para simular la aceleración con la gravedad).

 función jump (arriba, arriba) / * * Cambiamos J a su sprite saltador… * / document.getElementById ('j'). style.backgroundPosition = "-160px 0px"; / * * Aquí, debemos decidir si debe viajar hacia arriba o hacia abajo ... * / if (up && (document.getElementById ('j'). OffsetTop> 20)) // si actualmente se está moviendo hacia arriba, y tiene más de 20 píxeles desde la parte superior del escenario ... arriba = arriba - (arriba * .1); // Esto nos da un ligero arco en el salto, en lugar de un movimiento constante como ejecutar document.getElementById ('j'). Style.top = top + "px"; // Cambiar el temporizador de su posición = setTimeout (function () jump (up, top);, 60); // Luego vuelva a llamar a la función else if (arriba) // si actualmente está subiendo, pero está casi en la cima del escenario y necesita volver a bajar ... arriba = falso; // cambiamos la variable 'up' para que caiga en el siguiente temporizador de bucle = setTimeout (function () jump (up, top);, 60);  else if (! up && (document.getElementById ('j'). offsetTop < 115)) // if he is moving down, but is more than 5px from the ground, he will continue to fall… top = top + (top * .1); // His fall will slightly accelerate document.getElementById('j').style.top = top+"px"; timer = setTimeout(function()jump(up, top);, 60);  else  // If he is moving down, and he is within 5px of the ground… document.getElementById('j').style.top = "120px"; // Place him on the ground document.getElementById('j').style.backgroundPosition = "0px 0px"; // return to standing sprite // We do not call the loop anymore since he is standing still at this point  

¡Ahora podemos poner nuestras cuatro funciones en botones y tener un prototipo funcional de una animación de correr y saltar! Por favor, consulte el código fuente de esta página con comentarios y descargue la hoja de sprites que usé, si lo desea..


Conclusión

Ahora, aunque tenemos un prototipo en funcionamiento aquí, puede que note que tiene un poco de buggy. Cuando hace clic en más de un botón a la vez, el script intentará ejecutar ambos a la vez. O, si vuelves a hacer clic en el botón de salto hacia abajo, J continuará cayendo para siempre. Además, como mencioné anteriormente, tenemos variables globales en nuestro script, lo que significa que podría ser difícil agregar este código en una página existente sin bloquear otro JavaScript (que es también la razón por la que no intenté ejecutar este código en este blog). página). En nuestra próxima publicación, limpiaremos todos estos errores y hablaremos sobre el concepto de encapsulamiento y por qué es importante escribir un buen código en el mundo real.