Une animation JavaScript qui fonctionne (partie 2 de 4)

Dans le dernier post, nous avons introduit l'idée de sprite, un moyen facile d’animer en JavaScript qui fonctionne dans tous les navigateurs. Nous avons également expliqué comment configurer le sprite en tant qu’image de fond pour un div puis utilisez une ligne de JavaScript pour modifier la position de l’arrière-plan et lui donner l’impression que l’image a été déplacée..

Dans ce post, nous allons utiliser cette technique pour animer les mouvements de course et de saut. Afin de créer l'animation, nous devrons changer rapidement la position de l'arrière-plan à un intervalle régulier. Regardez encore le sprite que nous utilisons.


Rencontrez J, la mascotte de mon entreprise, Joust Multimedia.

Dans notre exemple, nous avons dix images au total: une de J debout face à la droite, trois de J courant vers la droite et une de J sautant vers la droite (avec le même nombre de chaque image tournée vers la gauche). Commençons par le faire courir à droite. Pour que notre image ressemble à une image courante, nous devrons faire deux choses: changer l’image-objet en une image différente et déplacer le div vers la droite.


Courir vers la bonne animation

Nous ne voudrons certainement pas rester coincés en cliquant sur différents boutons pour parcourir les sprites, nous aurons donc besoin de créer des fonctions qui le font automatiquement..

Pour notre fonction courante, nous voulons:

  1. Bouge le div légèrement vers la droite
  2. Passer à la prochaine image de l'animation
  3. Faire une pause d'une fraction de seconde (pour préserver l'illusion de "persistance de la vision")
  4. Boucle à nouveau la fonction

Heureusement, il existe un moyen facile de boucler avec des fonctions. Une commande native en JavaScript appelée setTimeout nous permettra de créer un délai, après quoi nous rappellerons la fonction (depuis l'intérieur de la fonction).

 function run_right () // Déplacez légèrement vers la droite… // Passez à l'image suivante de l'animation… // l'appel sera de nouveau «run_right» après 200 millisecondes setTimeout (function () run_right ();, 200); 

Nous avons donc maintenant une fonction qui s’appellera à nouveau cinq fois par seconde (ce qui sera assez rapide pour créer une animation pour nos besoins). Rappelez-vous ici que les navigateurs ne sont pas très précis avec leurs minuteries. Vous pouvez spécifier le délai en millisecondes, mais cela ne signifie pas que votre script s'exécutera exactement à ce moment.!

Notre prochain problème à résoudre est de savoir comment notre fonction va savoir à quel sprite changer. Dans notre exemple, nous devrons parcourir nos trois images (avoir quatre images d'animation au total). Pour ce faire, nous allons transmettre à notre fonction un peu d’information pour lui indiquer la diapositive sur laquelle basculer. Une fois dans la fonction, nous ferons un test qui vérifiera la diapositive sur laquelle nous devrions être placés, puis basculera la position d’arrière-plan sur la bonne image-objet. Lorsque nous rappellerons la fonction, nous passerons à la diapositive suivante comme argument..

 function run_right (slide) // Déplacez légèrement vers la droite… switch (slide) // cette instruction switch vérifie les différentes possibilités pour 'slide' cas 1: // si 'slide' est égal à '1'… document.getElementById ( 'j'). style.backgroundPosition = "-40px 0px"; setTimeout (function () run_right (2);, 200); Pause; cas 2: // si 'slide' est égal à '2'… document.getElementById ('j'). style.backgroundPosition = "-80px 0px"; setTimeout (function () run_right (3);, 200); Pause; cas 3: // si 'slide' est égal à '3'… document.getElementById ('j'). style.backgroundPosition = "-120px 0px"; setTimeout (function () run_right (4);, 200); Pause; cas 4: // si 'slide' est égal à '4'… document.getElementById ('j'). style.backgroundPosition = "-80px 0px"; setTimeout (function () run_right (1);, 200); Pause; 

Et maintenant, lorsque nous appelons la fonction pour la première fois, nous devons nous assurer de passer la diapositive de départ..

 

De même, pour déplacer notre div légèrement vers la droite, nous pouvons transmettre l'attribut initial gauche du div, puis déplacez le div légèrement à chaque fois que la fonction est appelée.

 fonction run_right (slide, left) left = left + 15; // Augmente son attribut de gauche de 15 pixels document.getElementById ('j'). Style.left = left + "px"; switch (slide) // cette instruction switch recherche différentes possibilités pour le cas "slide" cas 1: // si "slide" est égal à "1"… document.getElementById ('j'). style.backgroundPosition = "-40px 0px" ; setTimeout (function () run_right (2, gauche);, 200); Pause; cas 2: // si 'slide' est égal à '2'… document.getElementById ('j'). style.backgroundPosition = "-80px 0px"; setTimeout (function () run_right (3, gauche);, 200); Pause; cas 3: // si 'slide' est égal à '3'… document.getElementById ('j'). style.backgroundPosition = "-120px 0px"; setTimeout (function () run_right (4, à gauche);, 200); Pause; cas 4: // si 'slide' est égal à '4'… document.getElementById ('j'). style.backgroundPosition = "-80px 0px"; setTimeout (function () run_right (1, gauche);, 200); Pause; 

Et lorsque nous appelons la fonction pour la première fois, nous devons nous assurer de passer la position gauche actuelle de notre div.

 

Arrêt de l'animation

Nous avons donc maintenant une fonction qui, lorsqu'elle est appelée, animera J pour s’exécuter à droite. Malheureusement, nous n'avons aucun moyen de l'arrêter. Tout d'abord, nous devrons faire en sorte que la fonction cesse de s'appeler si J court jusqu'au bord de notre scène. Pour ce faire, chaque fois que la fonction est exécutée, nous allons vérifier un si déclaration pour voir si J a de la place pour continuer à courir. Si c'est le cas, nous allons exécuter la fonction comme d'habitude. Sinon, nous arrêterons d'appeler la fonction et le renverrons au sprite debout.

 function run_right (slide, left) // Si on peut ajouter 15 pixels à gauche et que le bord droit de J ne soit pas au bord droit de la scène… if ((left + 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";  

Enfin, nous voudrons avoir un moyen d’arrêter la fonction, le cas échéant. Nous pouvons régler le setTimeout () commande à une variable, puis arrêtez-le avec le clearTimeout () commander. Pour ce faire, nous devrons déclarer cette variable en dehors de la fonction afin de pouvoir y faire référence ultérieurement. Pour l'instant, nous allons le déclarer comme une variable globale. C'est une pratique de codage terrible, mais nous corrigerons cela dans le prochain post. Voici à quoi ressemble notre fonction.

 var timer; fonction run_right (diapositive, gauche) if ((gauche + 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";  

Et nous pouvons créer une autre fonction pour arrêter le chronomètre en cours et ramener l'image-objet à l'image debout..

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

Courir vers la gauche Animation

Maintenant, en empruntant le code de notre run_right fonction, nous pouvons créer une autre fonction pour faire un run_left fonction, avec seulement quelques modifications.

 fonction run_left (stage, left) if ((left - 15)> 0) left = left - 15; document.getElementById ('j'). style.left = left + "px"; switch (stage) case 1: document.getElementById ('j'). style.backgroundPosition = "-40px -50px"; timer = setTimeout (function () run_left (2, gauche);, 200); Pause; cas 2: document.getElementById ('j'). style.backgroundPosition = "-80px -50px"; timer = setTimeout (function () run_left (3, gauche);, 200); Pause; cas 3: document.getElementById ('j'). style.backgroundPosition = "-120px -50px"; timer = setTimeout (function () run_left (4, gauche);, 200); Pause; cas 4: document.getElementById ('j'). style.backgroundPosition = "-80px -50px"; timer = setTimeout (function () run_left (1, gauche);, 200); Pause;  else document.getElementById ('j'). style.backgroundPosition = "0px -50px"; 

Animation de saut

Enfin, nous devons créer une fonction de saut. Nous allons passer deux arguments à cette fonction, l’un permettant de savoir si le div est actuellement en train de monter ou de descendre et un autre qui suivra l’attribut supérieur actuel du div. Entre les deux, nous déterminerons dans quelle direction la div ensuite, et dans quelle mesure (nous allons déplacer le div moins de distance près de l'arc du saut pour simuler une accélération avec la gravité).

 saut de fonction (haut, haut) / * * Nous changeons J pour son sprite sautant… * / document.getElementById ('j'). style.backgroundPosition = "-160px 0px"; / * * Ici, nous devons décider s'il doit monter ou descendre… * / if (up && (document.getElementById ('j'). OffsetTop> 20)) // s'il monte actuellement, et il est à plus de 20 pixels du haut de la scène… top = top - (top * .1); // Cela nous donne un léger arc dans le saut, plutôt qu'un mouvement constant comme exécuter document.getElementById ('j'). Style.top = top + "px"; // change sa position timer = setTimeout (function () jump (haut, haut);, 60); // Ensuite, appelez à nouveau la fonction else if (up) // s'il monte actuellement, mais qu'il est presque au sommet de la scène et doit redescendre… up = false; // nous basculons la variable 'up' pour qu'il tombe dans la boucle suivante timer = setTimeout (function () jump (haut, haut);, 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  

Maintenant, nous pouvons mettre nos quatre fonctions dans des boutons et avoir un prototype fonctionnel d'animation en cours d'exécution et de saut! S'il vous plaît vérifier le code source de cette page avec des commentaires et télécharger la feuille de sprite que j'ai utilisé, si vous le souhaitez.


Conclusion

Maintenant, bien que nous ayons un prototype fonctionnel ici, vous remarquerez peut-être que c'est un petit buggy. Lorsque vous cliquez sur plusieurs boutons à la fois, le script tente de les exécuter simultanément. Ou, si vous cliquez à nouveau sur le bouton de saut en descendant, J continuera de tomber pour toujours. De plus, comme je l’ai mentionné précédemment, notre script contient des variables globales, ce qui signifie qu’il peut être difficile d’ajouter ce code dans une page existante sans écraser le code JavaScript (c’est aussi pourquoi je n’ai pas essayé d’exécuter ce code dans ce blog. page). Dans notre prochain article, nous allons nettoyer tous ces bugs et parler du concept de encapsulation et pourquoi il est important d'écrire du bon code dans le monde réel.