mgr inż. Wacław Libront * Bobowa 2017-2019
ZSO Bobowa, ul. Długoszowskich 1, 38-350 Bobowa, tel: 0183514009, fax: 0183530221, email: sekretariat@zsobobowa.eu, www: zsobobowa.eu
Animowany zegar w SVG
Tarcza
Zegar przygotowany w grafice wektorowej SVG będzie wyświetlał aktualny czas.
Pierwszy rysunek przedstawia obiekt trzy, składający się z trzech kwadracików. Grupa trzy zostanie obrócona jeszcze trzy razy. Zwróć uwagę, że kwadraciki rysowane są w tym samym miejscu, a drugi i trzeci mają zdefiniowany dodatkowy obrót. Kołowa tarcza zegara powinna być rysowana wcześniej, aby nie zasłaniała punktów godzinowych.
<svg width="300px" height="300px"> <!-- tarcza zegara - koło --> <circle cx="150" cy="150" r="135" stroke-width="12" stroke="black" fill="white"/> <!-- 3 punkty godzin: 0 - większy, 5 i 10 - mniejsze --> <g id="trzy"> <rect x="145" y="15" width="10" height="25" /> <rect x="145" y="15" width="10" height="15" transform="rotate(30,150,150)" /> <rect x="145" y="15" width="10" height="15" transform="rotate(60,150,150)" /> </g> <!-- 12 punktów na tarczy --> <use xlink:href="#trzy" /> <use xlink:href="#trzy" transform="rotate(90,150,150)" /> <use xlink:href="#trzy" transform="rotate(180,150,150)" /> <use xlink:href="#trzy" transform="rotate(270,150,150)" /> <!-- kropka na środku --> <circle cx="150" cy="150" r="7" stroke-width="2" stroke="black" fill="white" /> <circle cx="150" cy="150" r="6" stroke-width="2" stroke="white" fill="black"/> </svg> |
Wskazówki
Wskazówka sekundowa jest prostokątem i przechodzi przez środek tarczy (150,150). Ma szerokość 4, więc powinna być przesunięta o 2 punkty w lewo, do punktu (148). Do każdej wskazówki dorysujemy małe kółeczko, które będzie przesuwało się wraz z nią na brzegu tarczy.
Wskazówki grupujemy i nadajemy im identyfikatory: WSKsek, WSKmin, WSKgod. Wskazówki obejmujemy znacznikami:
Definicje wskazówek mogą być w dowolnym miejscu kodu, natomiast rysowane powinny być na tarczy, ale przed kropkami na środku. Wskazówki powinny być też rysowane w odpowiedniej kolejności – na samym wierzchu sekundnik. Każda wskazówka „wyposażona” została w Identyfikator, który posłuży do późniejszej obsługi animacji.
<defs> <g id="WSKsek"> <rect x="148" y="30" height="145" width="4" fill="red" /> <circle cx="150" cy="15" r="3" fill="red" /> </g> <g id="WSKmin"> <rect x="146" y="35" height="140" width="8" fill="black" /> <circle cx="150" cy="15" r="5" stroke-width="2" stroke="black" fill="white" /> </g> <g id="WSKgod"> <rect x="145" y="65" height="110" width="10" fill="black" /> <circle cx="150" cy="15" r="8" stroke-width="2" stroke="black" fill="white" /> </g> </defs> |
Animacja
Aby zegar pokazywał aktualną godzinę wykorzystamy język JavaScript. Najprostsza procedura animacyjna wykorzystuje rekurencję – w naszym przypadku wystarczy wywoływać procedurę co 1000 milisekund, czyli co 1 sekundę.
var czas; var skok=1000; function ANIMACJA() { clearTimeout(czas); czas=setInterval(animacja,skok); } animacja(); |
Będziemy modyfikować położenie wskazówek, dlatego potrzebne będzie utworzenie trzech zmiennych do obiektów SVG, które opisaliśmy odpowiednimi identyfikatorami. Standardowo czynimy to instrukcją dokument.getElementById, ale równie dobrze można to zrobić w prostszy sposób: var Wsek=SEK;
Następnie musimy nakazać obrót poszczególnych wskazówek o określony kąt – modyfikujemy obiekty SVG za pomocą polecenia setAttribute podając w postaci łańcuchów znakowych odpowiednie parametry.
<script> //zmienne do obiektów wskazówek var Wsek=SEK; var Wmin=MIN; var Wgod=GOD; //zmienne sterujące animacją var skok = 1000; var czas; function animacja() { //zmienne przechowujące czas var date = new Date(); var Dsek = date.getSeconds(); var Dmin = date.getMinutes(); var Dgod = date.getHours() % 12; //obracanie obiektów wskazówek Wsek.setAttribute('transform','rotate('+(Dsek * 6)+',150,150)'); Wmin.setAttribute('transform','rotate('+(Dmin * 6)+',150,150)'); Wgod.setAttribute('transform','rotate('+(Dgod * 30)+',150,150)'); //rekurencyjne wywołanie kolejnych animacji clearTimeout(czas); czas = setTimeout(animacja, skok); } animacja(); </script> |
Płynne przesuwanie wskazówek
Wskazówka przesuwa się skokowo – jeśli chcemy płynnej zmiany musimy wywoływać animację częściej,
na przykład co 1 milisekundę. Konieczne będzie
zmiana wartości zmiennej skok na 10
pobieranie ze zmiennej Date() milisekund za pomocą funkcji getMilliseconds()
var skok=10; //... w funkcji animacja var Dmil = date.getMilliseconds(); //sekundowa zmienia się co 10 milisekund Wsek.setAttribute('transform','rotate('+(Dsek * 6 + Dmil * 6/1000)+',150,150)'); //minutowa zmienia się co 1 sekundę Wmin.setAttribute('transform','rotate('+(Dmin * 6 + Dsek * 6/60)+',150,150)'); //godzinowa zmienia się co 1 minutę Wgod.setAttribute('transform','rotate('+(Dgod * 30 + Dmin * 6/12)+',150,150)'); |