JavaScript-animasjon som virker (del 2 av 4)

I det siste innlegget introduserte vi ideen om spriting, En enkel måte å animere i JavaScript som fungerer i alle nettlesere. Vi gikk også gjennom hvordan du konfigurerer sprite som et bakgrunnsbilde for en div og bruk deretter en linje med JavaScript for å endre bakgrunnsposisjonen slik at den vises som om bildet er flyttet.

I dette innlegget bruker vi denne teknikken til å animere både løpende og hoppende bevegelser. For å skape animasjonen må vi raskt endre bakgrunnsposisjonen med jevne mellomrom. Ta en titt igjen på sprite vi bruker.


Møt J, maskoten for firmaet mitt, Joust Multimedia.

I vårt eksempel har vi ti totalt bilder: en av J står vendt mot høyre, tre av J løper til høyre og en av J hopper mens du vender mot høyre (med samme nummer på hver ramme som vender mot venstre). La oss begynne med å få ham til å løpe til høyre. For å få bildet til å se ut som det kjører, må vi gjøre to ting: endre sprite til et annet bilde og flytte div mot høyre.


Kjører til høyre animasjon

Vi vil absolutt ikke være fast og klikke på forskjellige knapper for å bla gjennom sprites, så vi må lage noen funksjoner som gjør dette automatisk.

For vår løpende funksjon, vil vi:

  1. Flytt div mot høyre litt
  2. Flytt til neste animasjonsramme
  3. Pause i en brøkdel av et sekund (for å bevare visjonen "persistens av visjon")
  4. Gjenta funksjonen igjen

Heldigvis er det en enkel måte å løse med funksjoner. En innfødt kommando i JavaScript kalt setTimeout vil tillate oss å opprette en tidsforsinket forsinkelse, hvorefter vi vil ringe funksjonen igjen (fra innsiden av funksjonen).

 funksjon run_right () // Flytt litt til høyre ... // Endre til neste animasjonsramme ... // dette vil ringe 'run_right' igjen etter 200 millisekunder setTimeout (funksjon () run_right ();, 200); 

Så nå har vi en funksjon som vil kalle seg igjen fem ganger i sekundet (som vil være rask nok til å skape animasjon til våre formål). Husk her at nettlesere ikke er veldig nøyaktige med timere. Du kan spesifisere timing til millisekunden, men det betyr ikke at skriptet ditt vil kjøre på det tidspunktet akkurat!

Vårt neste problem å takle er hvordan fungerer vår funksjon som hvilken sprite å bytte til? I vårt eksempel må vi sykle frem og tilbake gjennom våre tre bilder (for å ha fire totalt animasjonsrammer). For å gjøre dette, skal vi passere vår funksjon litt informasjon for å fortelle den hvilken lysbilde å bytte til. En gang i funksjonen, vil vi gjøre en test som kontrollerer hvilket lysbilde vi skal være på, og bytt deretter bakgrunnsposisjonen til riktig sprite. Når vi kaller funksjonen igjen, vil vi passere neste lysbilde som argumentet.

 funksjon run_right (slide) // Flytt litt til høyre ... bryter (lysbilde) // denne bryteretningen sjekker for forskjellige muligheter for 'lysbilde' sak 1: // hvis 'lysbilde' er lik '1' ... document.getElementById ( 'j'). style.backgroundPosition = "-40px 0px"; setTimeout (funksjon () run_right (2);, 200); gå i stykker; tilfelle 2: // hvis 'lysbilde' er lik '2' ... document.getElementById ('j'). style.backgroundPosition = "-80px 0px"; setTimeout (funksjon () run_right (3);, 200); gå i stykker; tilfelle 3: // hvis 'lysbilde' er lik '3' ... document.getElementById ('j'). style.backgroundPosition = "-120px 0px"; setTimeout (funksjon () run_right (4);, 200); gå i stykker; tilfelle 4: // hvis 'lysbilde' er lik '4' ... document.getElementById ('j'). style.backgroundPosition = "-80px 0px"; setTimeout (funksjon () run_right (1);, 200); gå i stykker; 

Og nå når vi kaller funksjonen for første gang, må vi sørge for at vi passerer startskjermen.

 

Tilsvarende, for å flytte vår div til høyre litt, kan vi passere det opprinnelige venstreattributtet til div, flytt deretter div litt hver gang funksjonen kalles.

 funksjon run_right (lysbilde, venstre) left = left + 15; // Øk hans venstreattributt med 15px document.getElementById ('j'). Style.left = left + "px"; bryter (lysbilde) // denne bryteretningen sjekker for forskjellige muligheter for 'lysbilde' tilfelle 1: // hvis 'lysbilde' er lik '1' ... document.getElementById ('j'). style.backgroundPosition = "-40px 0px" ; setTimeout (funksjon () run_right (2, venstre);, 200); gå i stykker; tilfelle 2: // hvis 'lysbilde' er lik '2' ... document.getElementById ('j'). style.backgroundPosition = "-80px 0px"; setTimeout (funksjon () run_right (3, venstre);, 200); gå i stykker; tilfelle 3: // hvis 'lysbilde' er lik '3' ... document.getElementById ('j'). style.backgroundPosition = "-120px 0px"; setTimeout (funksjon () run_right (4, venstre);, 200); gå i stykker; tilfelle 4: // hvis 'lysbilde' er lik '4' ... document.getElementById ('j'). style.backgroundPosition = "-80px 0px"; setTimeout (funksjon () run_right (1, venstre);, 200); gå i stykker; 

Og når vi først ringe til funksjonen, må vi sørge for at vi sender den nåværende venstre posisjonen til vår div.

 

Stopper animasjonen

Så, nå har vi en funksjon som, når den kalles, vil animere J for å løpe til høyre. Dessverre har vi ingen mulighet til å stoppe det. Først av alt, må vi slutte å stoppe funksjonen, hvis J går til kanten av scenen. For å gjøre det, hver gang funksjonen kjører, vil vi sjekke en hvis uttalelse for å se om J har plass til å fortsette å løpe. I så fall vil vi kjøre funksjonen som vanlig. Hvis ikke, vil vi slutte å ringe funksjonen og returnere ham til stående sprite.

 funksjon run_right (lysbilde, venstre) // Hvis vi kan legge til 15 piksler til venstre og ha Js høyre kant ikke være på scenens høyre kant ... hvis ((venstre + 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";  

Til slutt vil vi ha en måte å stoppe funksjonen når det er nødvendig. Vi kan sette setTimeout () kommandoen til en variabel, og stopp den med cleartimeout () kommando. For å gjøre dette må vi deklarere den variabelen utenfor funksjonen, slik at vi senere kan referere til det. For nå vil vi erklære det som en global variabel. Dette er forferdelig kodingspraksis, men vi vil korrigere dette i neste innlegg. Slik ser vår funksjon ut.

 var timer; funksjon run_right (lysbilde, venstre) hvis ((venstre + 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";  

Og vi kan opprette en annen funksjon for å stoppe løpende timer og returnere sprite til stående bilde.

 funksjon stop_running () document.getElementById ('j'). style.backgroundPosition = "0px 0px"; cleartimeout (timer); 

Kjører til venstre animasjon

Nå ved å låne koden fra vår run_right funksjon, kan vi opprette en annen funksjon for å lage en run_left funksjon, med bare noen få modifikasjoner.

 funksjon run_left (scene, venstre) if ((left - 15)> 0) left = left - 15; document.getElementById ('j'). style.left = left + "px"; bytte (scenen) sak 1: document.getElementById ('j'). style.backgroundPosition = "-40px -50px"; timer = setTimeout (funksjon () run_left (2, venstre);, 200); gå i stykker; tilfelle 2: document.getElementById ('j'). style.backgroundPosition = "-80px -50px"; timer = setTimeout (funksjon () run_left (3, venstre);, 200); gå i stykker; tilfelle 3: document.getElementById ('j'). style.backgroundPosition = "-120px -50px"; timer = setTimeout (funksjon () run_left (4, venstre);, 200); gå i stykker; tilfelle 4: document.getElementById ('j'). style.backgroundPosition = "-80px -50px"; timer = setTimeout (funksjon () run_left (1, venstre);, 200); gå i stykker;  else document.getElementById ('j'). style.backgroundPosition = "0px -50px"; 

Hopping Animasjon

Til slutt må vi skape en hoppefunksjon. Vi vil passere to argumenter til denne funksjonen, en som vil spore om div Flytter nå opp eller ned og en annen som vil spore den nåværende toppattributtet til div. Mellom de to, vil vi avgjøre hvilken retning den div trenger å flytte neste, og hvor langt (vi vil flytte div mindre avstand nær bue av hoppet for å simulere akselerasjon med tyngdekraften).

 funksjonshopp (opp, topp) / * * Vi endrer J til hans hoppesprite ... * / document.getElementById ('j'). style.backgroundPosition = "-160px 0px"; / * * Her må vi avgjøre om han skal reise opp eller ned ... * / hvis (opp && (document.getElementById ('j'). OffsetTop> 20)) // hvis han nå flytter opp han er mer enn 20 piksler fra toppen av scenen ... topp = topp - (topp * .1); // Dette gir oss en liten bue i hoppet, i stedet for en konstant bevegelse som å kjøre document.getElementById ('j'). Style.top = top + "px"; // Endre stillingen timer = setTimeout (funksjon () hopp (opp, topp);, 60); // Deretter ringes funksjonen igjen ellers hvis (opp) // hvis han for tiden beveger seg, men han er nesten på toppen av scenen og må komme tilbake ned ... opp = false; // vi bytter opp-variabelen slik at han kommer til å falle i neste sløyfetimer = setTimeout (funksjon () hopp (opp, topp);, 60);  ellers hvis (! opp && (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  

Nå kan vi sette alle fire funksjonene i knapper og ha en fungerende prototype av en løpende og hoppende animasjon! Vennligst sjekk kildekoden for denne siden med kommentarer og last ned spritarket som jeg brukte, hvis du vil.


Konklusjon

Nå, selv om vi har en fungerende prototype her, kan du legge merke til at det er en liten buggy. Når du klikker på mer enn en knapp om gangen, vil skriptet prøve å kjøre begge samtidig. Eller, hvis du klikker hoppeknappen igjen på vei ned, fortsetter J å falle for alltid. Også, som nevnt tidligere, har vi globale variabler i skriptet vårt, noe som betyr at det kan være vanskelig å legge til denne koden i en eksisterende side uten å krasje andre JavaScript (det er derfor jeg forsøkte ikke å kjøre denne koden i denne bloggen side). I vårt neste innlegg vil vi rydde opp alle disse feilene og snakke om konseptet av innkapsling og hvorfor det er viktig å skrive god kode i den virkelige verden.