Strona główna » Algorytmy » Artykuły » Zegar binarny
 

Zegar binarny

Zegar binarny

Zegar binarny to skomplikowany zegar o nieskomplikowanej strukturze. Istnieją różne rodzaje takiego typu zegara. Najczęściej składa się on z 20 diod, które wyświetlają czas używając zapisu binarnego. Innymi słowy jest to świetny sposób, aby się wyróżnić i popisać wiedzą, ale wcześniej lepiej trochę poćwiczyć odczytywanie czasu z niego. Poniżej znajduje się przykład zegara binarnego, który wyświetla aktualny, lokalny czas na komputerze:

Odczytywanie godziny

Nietrudno pewnie się domyśleć, że aktualny czas można odczytać znając kod binarny. Na zegarku czas jest podzielony na 3 główne grupy - każda grupa składa się z dwóch kolumn. Pierwsza grupa to numer godziny, druga minut, a trzecia sekund. Ze względu na fakt, że maksymalna wartość minut i sekund to 59 to odczytywanie wartości z 6 diod mogłoby być nieco problematyczne, dlatego uproszczono odczytywanie zakodowanych liczb. Każda kolumna koduje jedną cyfrę. Kolejne koła od dołu do góry oznaczają kolejne potęgi dwójki. Podsumowując, aby otrzymać wartość grupy należy obliczyć wartości kolumn w grupie, a wyliczone wartości zapisać koło siebie. W celu odczytania kolumny należy zsumować wartości pól. Poniżej znajduje się przykład dla godziny 14:32:59:

143259::

Implementacja

Wstęp

Napisanie skryptu generujący zegar binarny jak na początku strony wymaga jedynie wiedzę dotyczącą wybierania cyfr z liczby oraz zamiany na postać binarną.

Aktualizacja stylu

(1.) Każde wyświetlane pole zawsze jest klasy .f, które ustala czas zapalania lampki. Jak wiadomo każde pole może być (2.) zapalone i (3.) zgaszone. Klasy .on i .off określają kolor diody: niebieska włączona, a szara wyłączona. Za styl wyświetlania zegara binarnego odpowiada wzór utworzony w grafice wektorowej SVG.

  1. .f{transition: fill 0.3s}
  2. .on{fill: #00F}
  3. .off{fill: #808080}

W celu optymalizacji zapalania i gaszenia lampek służy funkcja setClass(), która na podstawie pola obj oraz nowej klasy newclass określa czy istnieje potrzeba przypisywania nowej wartości klasy:

function setClass(obj, newclass){if(obj.className != newclass)obj.setAttribute("class", newclass);}

Aktualizacja pól

Każde pole ma swój unikalny identyfikator: pierwszy znak określa nazwę grupy, potem jest cyfra określająca numer kolumny w grupie (indeksowanie od 0), a potem indeks pola licząc od dołu (indeksowanie od 0). Funkcja updateLine() pozwala aktualizować pojedynczą kolumnę diod na podstawie wartości do wyświetlenia val. Do tego należy podać ile pól jest w danej kolumnie max oraz dwa pierwsze znaki identyfikatorów aktualizowanych pól name (grupa i numer kolumny w grupie).

function updateLine(val, max, name) {var a = Math.pow(2, max);while(max >= 0) {var obj = document.getElementById(name + max);setClass(obj, "f " + ((val >= a) ? "on" : "off"));val = val % a;a /= 2;max--;}}

(2.) Oblicz maksymalną wartość możliwą do przechowania w kolumnie. (3.) Aktualizuj każde pole: (4.) pobierz pole i (5.) sprawdź czy pole ma być zapalone. (6.) Pozbądź się zbędnej wartości i (7.) zmniejsz a dwukrotnie oraz (8.) przejdź do następnego pola. Warto zauważyć, że pola są aktualizowane od góry do dołu ze względu na wygodę.

Wyświetlanie aktualnego czasu

Do wyświetlania aktualnego czasu służy funkcja updateWatch(), która pobiera aktualną godzinę i na jej podstawie odpowiednio aktualizuje kolejne kolumny:

function updateWatch(){var d = new Date();updateLine(Math.floor(d.getHours()/10),1,"h0");updateLine(d.getHours() % 10,3,"h1");updateLine(Math.floor(d.getMinutes()/10),2,"m0");updateLine(d.getMinutes() % 10,3,"m1");updateLine(Math.floor(d.getSeconds()/10),2,"s0");updateLine(d.getSeconds() % 10,3,"s1");}

Autoaktulizacja

Zegarek można odświeżać co sekundę używając funkcji setInterval(). Ze względu na fakt, że strona może być ładowana w momencie wywołania skryptu to (1.) inicjalizacja odbędzie się dopiero, gdy dokument zostanie załadowany. Inicjalizacja polega na (2.) szybkiej aktualizacji tj. aktualizacja wstępna, a następnie (3.) ustalane jest co ile zegarek ma być aktualizowany.

document.addEventListener("DOMContentLoaded", function(){ updateWatch();setInterval(updateWatch, 1000);}, false);