de IQAndreas | 26 februarie 2014

Astăzi, vom realiza un ceas analogic clasic folosind caracteristicile pânzei găsite în HTML5. Ceasul pe care îl veți crea va arăta după cum urmează:

Acest ceas este de fapt live! Ar trebui să afișeze ora curentă a sistemului și să se actualizeze pe măsură ce trece fiecare secundă. În acest tutorial, veți afla totul despre cum să faceți acest lucru. Să începem.

Notă foarte importantă

Ca parte a creării ceasului nostru, veți obține puncte bonus dacă ascultați muzică cu tematică adecvată!

Noțiuni de bază

Vom adăuga în mod incremental HTML, CSS și JavaScript pentru a crea în cele din urmă minunatul nostru ceas analogic. Să începem mai întâi cu HTML de bază. Creați un nou document HTML și adăugați următorul cod:

Dacă previzualizați ceea ce avem până acum, nu există prea multe de văzut. Să remediem parțial acest lucru adăugând următoarele CSS între etichetele de stil:

Și, în sfârșit, să adăugăm ceva JavaScript pentru ca totul să înceapă să se miște! Adăugați următorul cod în etichetele de script:

Previzualizați-vă pagina în acest moment. Dacă pagina dvs. nu arată ca următoarea imagine, verificați de două ori dacă ați încărcat corect JavaScript-ul:

Dacă previzualizați

Acum, că avem elementele de bază în funcțiune, este timpul să trecem la.

Realizarea unui ceas digital

Deci vrei să faci un ceas analogic? Mai încet acolo, prietene!

Mai întâi vom adăuga un ceas digital. Motivul este că acest lucru ne va ajuta să învățăm să folosim clasa Date - clasa care conține o mulțime de funcționalități pe care le vom folosi pentru a afișa ora corectă. În al doilea rând, începând cu un ceas digital, depanarea ceasului nostru analogic va fi mult mai ușoară (credeți-mă în acesta).

Obținerea unei întâlniri

Dacă doriți să obțineți ora curentă în JavaScript, modul în care faceți acest lucru este prin simpla apelare a datei noi (). Editați codul JavaScript existent în funcția displayTime adăugând următoarele două linii evidențiate:

Dacă vă previzualizați documentul acum, veți vedea data afișată:

Deși acesta nu este un ceas în sens digital sau analogic, cel puțin ne deplasăm într-o direcție care pare corectă. Cu toate acestea, data afișată este MULT mai multe informații decât avem de fapt nevoie. Va trebui să scriem propriul nostru cod pentru a afișa ora, mai degrabă decât să ne bazăm pe toString () pentru a-l forma corect.

Pentru a ne ajuta să simplificăm puțin datele, clasa Date vine cu mai multe metode. În acest moment, tot ce trebuie să ne facem griji sunt funcțiile de timp:

Deoarece toate aceste valori sunt numere, deși nu este întotdeauna necesară, ar trebui să le convertim cu String (num) înainte de a încerca să le afișăm:

Codul dvs. complet din funcția displayTime va arăta acum după cum urmează:

Dacă previzualizați ceea ce aveți acum, veți vedea ceva care arată după cum urmează:

Păi funcționează, dar arată cam "amuzant". Mai întâi (dacă ignorați ora), veți observa că apare un timp neobișnuit de 18: 54: 1. Majoritatea ceasurilor digitale adaugă zerouri suplimentare la minut și a doua parte pentru a se asigura că valoarea este de două cifre, deci ceea ce ar trebui să afișeze cu adevărat ceasul este 18:54:01 .

Să adăugăm o funcție numită padZero care adaugă un zero la începutul numărului, dacă este necesar:

Această funcție padZero ia un număr ca argument. Dacă numărul apare cu mai puțin de două cifre (de asemenea mai puțin de 10), adăugăm un zero la începutul numărului pentru a face să apară ca două cifre cu un 0 care alcătuiește prima cifră. Dacă numărul este deja de două cifre, nu facem nimic și îl strângem doar ca parte a returnării acestuia.

Să folosim această funcție în exemplul nostru. Înlocuiți linia variabilă timeString cu următoarea versiune modificată:

JavaScipt-ul nostru complet în acest moment va arăta astfel:

În acest moment, timpul dvs. se va afișa acum mai corect, fără să apară numere dintr-o singură cifră fără un 0 în fața lor. Există totuși un lucru care va părea ciudat.

Dar asta e timpul armatei!

Dacă sunteți o țară care nu folosește ceasul de 24 de ore (tuse, tuse, America), puteți fi confuz sau cel puțin deranjat de faptul că valoarea orei de pe ceasul nostru este mai mare de 12. Deși ceasul de 24 de ore este mai clar și mai puțin ambiguu, la fel de bine l-am putea converti într-un ceas de 12 ore doar pentru ca toată lumea de pe glob să îl poată înțelege.

Vom scrie o funcție care convertește ora la ora de 12 ore. În primul rând, vom folosi operatorul de modul pentru a ne asigura că ora este o valoare între 0 și 11. Dar din moment ce nu există 0 oră în ceasul de 12 ore, ne asigurăm că valoarea nu se afișează niciodată schimbând-o în 12 in schimb.

Pentru a face acest lucru, îndepliniți funcția formatHour:

De asemenea, mai avem nevoie de o modalitate de a spune dacă să folosim AM sau PM. Modul în care este configurat este un pic dificil (comanda este 11 AM, 12 PM, 1 PM, când într-adevăr, ar avea mai mult sens să apelăm acel 12 AM). Ați putea scrie o funcție care face acest lucru cu atenție, dar vom lua o comandă rapidă care poate să nu fie foarte clară. dar funcționează:

După ce ați adăugat funcțiile formatHour și getTimePeriod în codul dvs., continuați și modificați variabila timeString din displayTime din nou cu următoarele:

Dacă vă previzualizați pagina din nou, acum veți vedea timpul afișat după cum urmează:

Tadaaa! Acum aveți un ceas digital. Nu se actualizează în fiecare secundă, dar este OK pentru moment. Vom aborda acest detaliu ca parte a creării ceasului nostru analog în curând.

Desenarea ceasului analogic

Aici începe distracția! Vă amintiți acel element care ne-a așteptat atât de răbdător? Este un pic dificil de văzut unde se află pe pagină, așa că hai să „aducem înainte” mutând conturul nostru de la ceasul digital la pânza noastră.

În CSS, asigurați-vă că linia evidențiată apare în regula stilului #clock spre deosebire de regula # stilului de timp curent:

Dacă vă previzualizați pagina, veți vedea acum pânza conturată spre deosebire de timpul în sine:

Testarea pânzei

Să ne asigurăm că pânza noastră funcționează corect trasând câteva linii pe ea. Va fi la îndemână să lăsați ceasul digital acolo (astfel putem vedea ora curentă deasupra ceasului nostru analogic), așa că lăsați vechiul JavaScript în funcția displayTime acolo unde este și adăugați codul pentru ceasul analogic imediat după el.

Mai întâi vom face o linie roșie din centrul ceasului spre dreapta (ora 3). Adăugați următoarele linii evidențiate la funcția displayTime:

Dacă previzualizați acest lucru, veți vedea o linie roșie continuă afișată în mijlocul ceasului analogic. Să mai facem o schimbare. Să adăugăm o linie neagră de la centru la vârf (ora 12). Rețineți că nu trebuie să recreăm variabilele pânză sau context, putem doar să le reutilizăm pe cele pe care le-am creat pentru linia roșie.

Adăugați acest cod imediat după linia context.stroke ():

Dacă previzualizați documentul acum, veți vedea o linie neagră pentru a completa linia roșie:

Wohoo, acum este ora 3 în fiecare zi; fara scoala!

Chiar dacă este garantat că acest ceas este corect de două ori pe zi, totuși nu este suficient de practic pentru scopurile noastre. Avem nevoie de mai mult control asupra direcției acelor brațe.

Atenție: Math Ahead!

Din păcate, această parte necesită o anumită trigonometrie. Știind doar elementele de bază ar trebui să te ducă departe, dar un lucru pe care poate nu l-ai folosit este Tau constant. Gândiți-vă la aceasta ca la o versiune mai bună a Pi când vine vorba de a face față lucrurilor în cercuri. Puteți afla mai multe despre Tau (și PI) din următorul videoclip al Academiei Khan.

Asa de. ca parte a explicării a ceea ce vom face, să scoatem mental brațul negru pentru moment și să ne concentrăm doar pe rotirea corectă a brațului roșu. Când brațul orar indică ora 2, a dispărut 2/12 a drumului în jurul ceasului. Deci, la ora 2, mâna orelor noastre arată ce este TAU * (2/12) radiani.

Dacă dorim să obținem automat această valoare prin cod, am face ceva de genul următor:

În continuare trebuie să știm lungimea brațului; deocamdată, vom face brațul atâta timp cât raza ceasului, astfel încât să indice cea mai mare margine a ceasului. Tot ce trebuie să facem este să conectăm aceste numere la codul existent. Găsiți comentariul care spune Pune matematica aici, și înlocuiți-l cu aceste linii de cod:

Și acum o desenăm. Găsiți următoarele rânduri:

Acum, înlocuiți cele două linii evidențiate cu următoarele două rânduri:

Dacă totul este corect, atunci când vă previzualizați pagina acum, ar trebui să vedeți mâna orelor care indică oricare oră este în prezent pentru dvs.:

Ajungem acolo. încet.

Adăugarea celorlalte brațe

Avem doar mâna orelor configurată corect acum. Acum, am putea copia și lipi codul pentru afișarea orei, dar îl putem edita pentru minute și secunde. Dezavantajul acestui plan strălucit este că ar fi nevoie de mult cod și nu ne-ar face dezvoltatori foarte buni. În schimb, putem pune totul într-o funcție care atrage brațele pentru noi.

Acest lucru va necesita eliminarea și înlocuirea unui cod. În interiorul funcției displayTime, ștergeți totul după declarația Math.TAU. Funcția dvs. displayTime ar trebui să arate după cum urmează:

Acum, după declarația Math.TAU, continuați și adăugați următoarele linii de cod:

Funcția dvs. full displayTime ar trebui să arate acum după cum urmează:

Dacă vă previzualizați documentul acum, veți vedea ceva care arată după cum urmează:

Acum ar trebui să vedeți linii roșii solide care reprezintă ora, minutul și a doua valoare a timpului dvs.

Luați câteva momente pentru a analiza codul și a vedea cum totul pare să funcționeze împreună. După ce ați făcut acest lucru, trebuie să ținem cont de un lucru important. Să presupunem că ora este în prezent 3:10; conform codului nostru, valoarea orei este 3, deci a călătorit 3/12 în jurul ceasului (TAU * (3/12) radiani). Valoarea minutului este 10, dar nu a călătorit 10/12 în jurul ceasului! A călătorit doar 10/60 în jurul ceasului (TAU * (10/60) radiani).

De aceea, în loc să trecem valoarea curentă (ca în exemplu, 3 pentru oră și 10 pentru minut) trecem o variabilă numită progres la funcția drawArm care reprezintă cât de departe a călătorit brațul. O valoare de 0 înseamnă că ești la prânz și 0,5 înseamnă că îndreptați direct în jos la ora 6 și o valoare de 0,25 înseamnă că brațul este îndreptat spre dreapta către cele trei de pe ceas.

Acum, că aveți o idee mai bună despre modul în care funcționează codul nostru, haideți să remediem ceva care este cam enervant în ceea ce privește ceasul chiar acum. Ei bine, putem vedea brațele, dar toate arată la fel. Să adăugăm câțiva parametri la funcția noastră drawArm (), astfel încât să putem face diferența dintre ei.

Modificați (sau înlocuiți) funcția drawArm cu următoarele:

Similar cu ceea ce am făcut mai sus cu progresul, parametrul armLength poate fi o valoare din 0 la 1. O valoare 1 înseamnă că ajunge până la marginea ceasului, în timp ce o valoare de 0,5 înseamnă că micuțul încăpățânat merge doar pe jumătate. În acest fel, chiar dacă ne schimbăm dimensiunea ceasului, nu ne va încurca brațele.

Acum îți poți personaliza brațele după conținutul inimii tale! Locul în care specificați acești parametri este atunci când apelați drawArm și se face în următoarele trei linii:

Am vrut să rămân la fel de fidelă aspectului de ceas „clasic”, așa că mergeți mai departe și înlocuiți aceste linii cu următorii parametri pentru culoarea și dimensiunea pe care le-am ales:

Dacă vă previzualizați documentul acum, ceasul ar trebui să arate după cum urmează:

Credit suplimentar

Încercați să setați parametrii brațului la valori negative sau valori mai mari de 1 și vedeți ce distracție poate ieși din el.

Efectuarea mișcării brațelor ceasului

Ceasul arată minunat, dar este cam cam așa. nu se mișcă. Nu mai sunt 10:10:55 PM, așa este acum 10 secunde. Nu ar fi grozav dacă mâinile ceasului se mișcau singure?

De ce nimic nu se mișcă

În loc să ne scufundăm mai întâi pentru a ne mișca ceasul analogic, vom face mai întâi o vizită la ceasul nostru digital original. Să ne uităm la prima parte a codului nostru (chiar începutul, care ne spune să nu desenăm ceasul până când nu s-a încărcat întreaga pagină):

Acest cod este apelat o dată, deoarece pagina se încarcă o singură dată. Pentru a conduce acest punct cu adevărat acasă, aceasta înseamnă că funcția noastră displayTime () se execută o singură dată. Cum am merge să-l rulăm din nou și din nou și din nou. și din nou?

Introducerea setInterval ()

Funcția utilă setInterval () va rula o funcție din nou și din nou, cu un spațiu între fiecare apel. Această funcție are doi parametri:

  1. Funcția pe care doriți să o rulați
  2. Numărul de milisecunde dintre fiecare dată când îl rulați

O milisecundă este 1/1000 de secundă. Dacă doriți să rulați o funcție (cum ar fi. O funcție fictivă checkEmail) la fiecare 5 secunde (5000 milisecunde), veți utiliza următorul cod:

Acest lucru va face ca JavaScript să acționeze astfel (observați că începe prin așteptare):

Dacă doriți să opriți setInterval de la rulare, trebuie să țineți evidența valorii pe care setInterval o întoarce atunci când îl porniți pentru prima dată și apoi treceți aceeași valoare la clearInterval. Probabil că sună confuz, deci următorul exemplu arată cum funcționează:

Acum, că ați văzut elementele de bază ale setInterval, haideți să folosim puterile sale magice cu ceasul nostru.

Actualizarea ceasului nostru

În acest moment, avem un ascultător de evenimente care ascultă evenimentul DOMContentLoaded/span> și apelează funcția displayTime:

Să schimbăm asta. În loc ca ascultătorul nostru de evenimente să apeleze displayTime, să îl modificăm pentru a apela o funcție numită startTimer. În timp ce ne aflăm, să adăugăm și funcția startTimer:

Ceea ce am făcut este ca pagina noastră să apeleze funcția startTimer odată ce se încarcă. Această funcție conține funcția setInterval care apelează displayTime la fiecare 1000 de milisecunde (aka 1 secundă). De asemenea, un lucru de remarcat. Deoarece vrem să afișăm ora imediat după încărcarea paginii și nu așteptăm 1 secundă pentru ca apelul setInterval să se afișeze Timpul pentru a intra în direct, apelăm displayTime în mod explicit o dată în plus față de apelul setInterval:

Continuați și previzualizați documentul acum și vedeți cum arată totul. După câteva secunde, veți vedea ceva care arată astfel:

În mod clar, ceva nu este în regulă. Ce se întâmplă este simplu. În fiecare secundă, desenezi linii pe pânză. Problema este că nu spuneți niciodată pânzei să elimine niciuna dintre liniile vechi, așa că le menține acolo. Puteți șterge o regiune a pânzei utilizând funcția clearRect (). Dacă doriți să ștergeți întreaga pânză (ceea ce facem în acest caz) trebuie doar să adăugați următoarea linie evidențiată înainte de apelul dvs. la funcțiile drawArm:

După ce ați adăugat această linie, continuați și previzualizați pagina încă o dată. De data aceasta, ceasul dvs. se va actualiza în fiecare secundă fără a lăsa în urmă o urmă a trecutului său. Puteți vedea sursa completă în exemplul de ceas analogic pe care l-am creat ca parte a verificării tuturor codului de aici, face ceea ce face.

Concluzie

Acum, când ceasul nostru analogic este terminat, nu vom mai avea nevoie de cel digital. Sunteți liber să îl ștergeți și codul aferent sau pur și simplu îl puteți ascunde cu CSS:

Deși ceasul nostru analogic este acum funcțional, nu este încă foarte frumos; sunt mult mai multe lucruri care se pot face cu el! Aceasta este partea în care devii creativ. Adăugați propriile atingeri personale la ceas și spuneți-ne ce ați făcut în acest fir.