Analógové hodiny v JavaScripte
Možno by sa na vaše stránky hodili animované analógové hodiny. Ak poznáte JavaScript, nebude to veľký problém. Náš výtvor bude vyzerať nejako takto:
HTML 5 kostra
Najprv si predchystajú kostru HTML 5 dokumentu. Jediným dôležitým prvkom
je práve plátno:
<canvas id="canvas" width="600" height="600"></canvas>
:
<!DOCTYPE html> <head> <title>Hodiny</title> </head> <body> <canvas id="canvas" width="600" height="600"></canvas> <script> <!-- Zde budou hodiny --> </script> </body> </html>
Javascript
Pridáme základ nášho skriptu:
let canvas = document.getElementById("canvas"); let ctx = canvas.getContext("2d"); let radius = canvas.height / 2; ctx.translate(radius, radius); radius = radius * 0.90; setInterval(drawClock, 1000); // ...
Z dokumentu si vytiahneme <canvas>
(plátno)
podľa jeho identifikátora a kresliace kontext nastavíme práve z "plátna" na
2D.
Premenná radius
, teda polomer, bude mať hodnotu polovice
výšky kontextu. Väčšinou obrazovky bývajú širší ako vyšší.
Počiatok kontextu presunieme do stredu plátna a polomer zmenšíme asi na 90%,
to aby sa krásne zmestil rám hodín aj s rezervou.
Nakoniec budeme v intervaloch 1 sekundy volať funkciu, ktorá bude hodiny vykresľovať.
Vykresľovací funkcie
Teraz sa pozrieme na hlavné vykresľovací funkciu, ktorá v podstate volá funkcie pre kreslenie rámu hodín, ciferníka a ručičiek. Vlastne vykresľujú čas, pretože podľa neho sa potom kreslí ručičky. Tu toho k vysvetľovaniu veľa nebude:
//... function drawClock() { drawFace(ctx, radius); drawNumbers(ctx, radius); drawTime(ctx, radius); } //...
Vykresľovací kód sme teda pre prehľadnosť rozdelili na 3 ďalšie funkcie, poďme si ich nad funkciou definovať.
drawFace()
Nasledujúce funkcie si bude žiadať trochu bližší pohľad, budeme si ju teda popisovať po častiach:
// ... function drawFace(ctx, radius) { ctx.beginPath(); ctx.arc(0, 0, radius, 0, 2 * Math.PI); ctx.closePath(); ctx.fillStyle = 'white'; ctx.fill();| // ...
- Pripravili sme si cestu pomocou
beginPath()
, pretože čiary a iné takéto veci sa vcontext
kreslí pomocou cesty. - Cesta je oblúk, ktorý má počiatok v stredu kontexte, celkový uhol
2PI
a polomerradius
. Prečo práve 2pi snáď hovoriť ani nemusím, dúfam (uhol plného kruhu, pretože ciferník je kruh). - Nastavili sme bielu výplň, pretože sa môže stať, že hodiny niekto vloží na veľmi farebné pozadie a nebudú vidieť ani ručičky, ani čísla. Tým hodiny strácajú zmysle.
- A celý kruh sme vybielili pomocou
fill()
V ďalšej časti funkcie si pripravíme gradientný výplň rámu hodín a rovno ju aj nakreslíme.
Všimnite si, že všetky parametre udávame ako percentuálny časť polomere, čo je výborné, ak si hodiny budete chcieť zväčšiť alebo zmenšiť. Potom stačí len zmeniť veľkosť plátna.
// ... let grad = ctx.createRadialGradient(0, 0, radius * 0.95, 0, 0, radius * 1.05); grad.addColorStop(0, '#333'); grad.addColorStop(0.5, 'white'); grad.addColorStop(1, '#333'); ctx.strokeStyle = grad; ctx.lineWidth = radius*0.1; ctx.stroke(); // ...
- Radiálne gradient má niekoľko argumentov -
createRadialGradient(x_0, y_0, r_0, x_1, y_1, r_1)
. Pre os X je to počiatok v stredu a polomer (tu 95% polomeru)), pre os Y je polomer 105% polomeru. - Farebné nastavenie: od počiatku je šedá (skoro čierna) idúce do bielej a potom zas späť do šedej.
- Štýl čiary nastavíme na náš gradient a silu čiary na 10% polomeru.
- Posledný príkaz vykreslí nami nastavenú čiaru, idúce po ceste z predošlej časti funkcie.
Ešte urobíme takú malú bodku za hodinovým rámom, teda na ňom. A to presne uprostred, v mieste, odkiaľ budú vychádzať ručičky. Tu už toho tiež k popisu moc nebude:
//... ctx.beginPath(); ctx.arc(0, 0, radius * 0.1, 0, 2 * Math.PI); ctx.closePath(); ctx.fillStyle = '#333'; ctx.fill(); //... }
drawNumbers()
Teraz sa pustíme do ciferníku. Použijem arabské číslice, ale ak sa vám
chce, urobte si napríklad rímske. To však budete potrebovať jedno pole
navyše:
["I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X", "XI", "XII"];
.
Kód metódy drawNumbers()
je nasledovné:
//... function drawNumbers(ctx, radius) { let num; ctx.font = radius * 0.15 + "px arial"; ctx.textBaseline = "middle"; ctx.textAlign = "center"; //...
Tu sme si len nastavili veľkosť fontu na 15% priemeru vykresľovanie pokiaľ možno v centre kontexte. Pridáme ďalšie kód:
//... for (num = 1; num < 13; num++) { let ang = num * Math.PI / 6; ctx.rotate(ang); ctx.translate(0, -radius * 0.85); ctx.rotate(-ang); ctx.fillText(num.toString(), 0, 0); ctx.rotate(ang); ctx.translate(0, radius * 0.85); ctx.rotate(-ang); } //...
Tento kód je celkom jednoduchý. Cyklus beží od 1
do
12
a spočítame potrebný uhol, umiestnenie danej číslice na
ciferníku. Počiatok súradníc kontexte o tento uhol otočíme, posunieme o
85% polomeru. Rotáciu os vrátime späť a nakreslíme číslo. Potom opäť
počiatok súradnicovej sústavy otočíme a počiatok vrátime späť do
pôvodnej pozície i smeru. Potom môžeme maľovať druhé číslo v ďalšej
iterácii.
drawHand()
Podobne budeme maľovať aj ručičky. Funkciu odovzdáme kontext a uhol natočenia ručičky. Je to vlastne smer vektora a jeho veľkosť. Posledný parameter je šírka čiary:
//... function drawHand(ctx, pos, length, width) { ctx.lineWidth = width; ctx.lineCap = "round"; ctx.beginPath(); ctx.moveTo(0, 0); ctx.rotate(pos); ctx.lineTo(0, -length); ctx.stroke(); ctx.rotate(-pos); } //...
drawTime()
Posledná funkcia bude počítať smer ručičiek v závislosti na čase:
- Hodinovú ručičku nastavíme na uhol celých hodín a pripočítame pomernej uhly minút a sekúnd (pretože chceme, aby ju neovplyvňoval len počet celých hodín).
- Minútová ručička sa opraví o pomerný uhol ručičky sekundové.
Kód je nasledujúci:
function drawTime(ctx, radius) { let now = new Date(); let hour = now.getHours(); let minute = now.getMinutes(); let second = now.getSeconds(); // ********** Hodinová ručička; délka = 50% poloměru hour = hour % 12 // Je třeba zohlednit i posun pro minuty a sekundy hour = (hour * Math.PI / 6) + (minute * Math.PI / (6 * 60)) + (second * Math.PI / (360 * 60)); drawHand(ctx, hour, radius*0.5, radius*0.07); // ********* Minuty; délka = 80% poloměru minute = (minute * Math.PI / 30) + (second * Math.PI / (30 * 60)); drawHand(ctx, minute, radius*0.8, radius*0.07); // ********* Sekundy; délka = 90% poloměru second = (second * Math.PI / 30); drawHand(ctx, second, radius*0.9, radius*0.02); }
Tak a máme celý skript. Môžete ho vyskúšať a pochváliť sa krásnymi hodinami:
Samozrejme, že zdrojový kód je priložený v archíve.
Stiahnuť
Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami
Stiahnuté 122x (1.98 kB)
Aplikácia je vrátane zdrojových kódov v jazyku JavaScript