12
6
3
9

Eine analoge Uhr mit Zeigern

Nachdem wir schon verschiedene Varianten von Uhren programmiert haben, wollen wir nun eine analoge Uhr mit Zeigern programmieren.

Das klingt eigentlich sehr einfach, gestaltet sich im Detail aber etwas kompliziert. Deshalb versuche ich es einfach und Schritt für Schritt zu erklären.

Ziel ist es also eine Uhr zu erstellen die die Uhrzeit mittels Zeigern anzeigt die sich im Kreis drehen. Der Kreis soll die Stunden 3, 6, 9 und 12 anzeigen. Es soll ein Stunden, Minuten und Sekunden Zeiger angezeigt werden, die sich drehen.

Der Quellcode

Ich möchte euch hier kurz erklären wie ich mittels CSS die Uhr "gezeichnet" habe. Zuerst habe ich einfach einen Kreis gezeichnet:

    <div  style="width:100px;
    height:100px;
    border-color:black;
    border-width:5px;
    border-radius:100%;
    background-color:#dfdfdf;
    border-style:solid;
    position:relative;
    "> 
    </div>
    

Der Kreis ist eigentlich ein Viereck 100 mal 100 Pixel groß und hat einen Border-Radius von 100%. Dadurch wird das Viereck zum Kreis.
Außerdem habe ich noch einen Hintergrund und einen Rahmen angegeben, damit man den Kreis besser sieht.
Wichtig ist die Angabe "border-style:solid" damit der Rahmen auch sichtbar ist.

Hier kurz die einzelnen Eigenschaften des Kreises, damit Ihr wisst wofür die einzelnen Dinge stehen:

width:100px Gibt die breite des Kreises an.
height:100px Gibt die höhe des Kreises an.
border-color:black; Gibt die Farbe des Kreises an.
border-width:5px; Gibt die Breite des Rahmens des Kreises an.
border-radius:100%; Gibt den Radius des Kreises an.
background-color:#dfdfdf; Gibt die Hintergrundfarbe des Kreises an.
border-style:solid; Gibt die Art des Rahmens vom Kreis an.
position:relative; Gibt die Position des Kreises an.

Als nächses kommen die Zeiger. Ich habe mit dem Sekundenzeiger angefangen, damit ich schneller sehe wie er sich dreht.
Hierfür habe ich ein Viereck in den Kreis hinein gezeichnet:

<div id="analogWatch_Seconds"  style="
border-right-width: 1px;
border-top-width: 1px;
border-bottom-width: 1px;
border-left-width: 1px;
border-style: solid;
border-color: black;
width: 45px;
height: 45px;
margin-top:0px;
transform-origin:left bottom;
position:absolute;"> 
</div>

Dieses Viereck ist nur 45 mal 45 Pixel groß und hat einen Rahmen von 1 px.
Eventuell seht ihr schon, dass der rechte Rahmen genau der Zeiger auf der 12 ist. Deshalb entfernen wir die anderen Rahmen, indem wir die broder-width auf 0px setzen, außer bei border-right-width:

    <div id="analogWatch_Seconds" style="
    border-right-width: 1px;
    border-top-width: 0px;
    border-bottom-width: 0px;
    border-left-width: 0px;
    border-style: solid;
    border-color: black;
    width: 45px;
    height: 45px;
    margin-top:0px;
    transform-origin:left bottom;
    position:absolute;">
    </div>

Somit haben wir nur eine Seite vom Viereck und das ist unser Sekundenzeiger.

Nun fügen wir einen zweiten Zeiger für die Minuten ein. Diesen zeichne ich in Grün, damit wir diesen Unterscheiden können:

    <div style="width:100px;
    height:100px;
    border-color:black;
    border-width:5px;
    border-radius:100%;
    background-color:#dfdfdf;
    border-style:solid;
    position:relative;"> 

        <div id="analogWatch_Seconds" 
        style="
        border-right-width: 0px;
        border-top-width: 0px;
        border-bottom-width: 0px;
        border-left-width: 1px;
        border-style: solid;
        border-color: black;
        width: 45px;
        height: 45px;
        margin-left:49px;
        margin-top:0px;
        transform-origin:left bottom;
        position:absolute;">
        </div> 
  
        <div id="analogWatch_Minutes"  
        style="
        border-right-width: 0px;
        border-top-width: 0px;
        border-bottom-width: 0px;
        border-left-width: 1px;
        border-style: solid;
        border-color: green;
        width: 45px;
        height: 45px;
        margin-left:49px;
        margin-top:0px;
        transform-origin:left bottom;
        position:absolute;
        transform:rotate(30deg);">
        </div> 
    </div>

Der zweite Zeiger wurde mit der CSS Eigenschaft "transform:rotate(30deg)" etwas gedreht, damit sich die Zeiger nicht überlagern. Nun sieht es schon eher nach einer Uhr aus. Damit lassen wir die Zeiger gleich mittels Javascript drehen.

transform:rotate(30deg) Dreht den "Zeiger" um 30 Grad nach rechts

Probiert es gerne hier mal aus und ändert unter "transform:rotate(30deg);" den Wert und setzt diesen auf "transform:rotate(90deg);" oder "transform:rotate(180deg);":

See the Pen Untitled by Fabian (@Onkelllepie) on CodePen.

Nun soll sich der Zeiger natürlich automatisch drehen. Dafür benötigen wir etwas Javascript um die Position unseres Viereckes zu verändern.

Probiert es gerne mal aus:

See the Pen Untitled by Fabian (@Onkelllepie) on CodePen.

Ihr habt sicher gesehen, dass man nun zwischen HTML und Javascript hin und her schalten kann. Das HTML hat sich zum obigen Beispiel nicht geändert. Allerdings ist nun etwas Code hinzugekommen.
Dieser umfasst eine Methode "watchRotate_Simple" und macht folgendes. Mit

const date_fast = new Date();
//Sekunden-Zeiger
var secs = date_fast.getSeconds();
var rotationSeconds = (secs / 60) * 360;

wird die aktuelle Sekunde ermittelt und die Rotation (also die Drehbewegung) unseres Sekundenzeigers berechnet. Hierfür wird die aktuelle Sekunde durch 60 geteilt und mit 360 multipliziert.
Mittels der rotate Eigenschaft wird unser "Zeiger" in die richtige Richtung gedreht. Dabei wird der ermittelte Wert "rotationSeconds" mittels der CSS Funktion "rotate" gesetzt:

document.getElementById("analogWatch_Seconds").style.transform = "rotate(" + rotationSeconds + "deg)";

Allerdings dreht sich nun nur der Sekundenzeiger. Also müssen wir die Methode erweitern damit sich auch der Minutenzeiger dreht:

See the Pen Untitled by Fabian (@Onkelllepie) on CodePen.

Ihr seht nun, dass sich der Minutenzeiger genau dann bewegt, wenn die volle Minute (also 60 Sekunden) erreicht sind. In einem weiteren Beispiel erkläre ich, wie man das Problem auch lösen kann, damit sich der Minutenzeiger auch zwischen den Sekunden dreht.
Jetzt fügen wir nur noch den Stundenzeiger (blauer Zeiger) in das HTML ein, sowie das Javascript, damit sich auch dieser bewegt:

    <div id="analogWatch_Hours" style="
    border-right-width: 0px;
    border-top-width: 0px;
    border-bottom-width: 0px;
    border-left-width: 1px;
    border-style: solid;
    border-color: blue;
    width: 45px;
    height: 45px;
    margin-left:49px;
    margin-top:0px;
    transform-origin:left bottom;
    position:absolute;">
    </div>

und hier das Javascript:

    //Stunden-Zeiger
    var hours = date_fast.getHours();
    var rotationHours = ((hours - 12) / 12) * 360;

    document.getElementById("analogWatch_Hours").style.transform = "rotate(" + rotationHours + "deg)";

Hier könnt ihr euch den kompletten Code anschauen:

See the Pen Untitled by Fabian (@Onkelllepie) on CodePen.

Da es sehr lange dauert den Stundenzeiger zu beobachten, könnt ihr mit folgendem Code einen "Schnell-Modus" aktivieren. Das heißt die Zeit läuft viel schneller als Normal. Dabei lasse ich den Minuten-Zeiger im Sekundentakt drehen und man kann so schneller sehen wie sich der Stundenzeiger bewegt. Die Uhrzeit stimmt damit aber natürlich nicht mehr.
Der Trick ist, einfach bei jedem Durchlauf wenn sich der Sekundenzeiger dreht, einfach 60.000 Millisekunden (also 1 Minute) der aktuellen Zeit hinzuzufügen.
Es gibt sicher noch andere Wege dies zu erreichen. Probiert euch gerne aus:

See the Pen Untitled by Fabian (@Onkelllepie) on CodePen.

Eine genaue Erklärung wie das funktioniert erstelle ich bald und verlinke es hier.

Ich finde es einfacher, wenn auch die Zahlen an der Uhr zu sehen sind, damit man besser sieht welche Uhrzeit gerade ist. Deshalb hier noch der vollständige HTML Code mit Zahlen an der Uhr:

See the Pen Untitled by Fabian (@Onkelllepie) on CodePen.

Den vollständigen Code findet ihr im CodePen. Diesen könnt ihr einfach in ein Textfile speichern und lokal auf eurem PC ausführen. Ihr könnt ihn hier auch direkt herunterladen. Einfach diese Seite mittels Rechtsklick speichern und dann in einem Editor öffnen.

Nun ist die Uhr fertig. Allerdings ist euch vielleicht aufgefallen, dass sich der Minutenzeiger nur zur vollen Minute und der Stundenzeiger nur zur vollen Stunde weiter drehen.
Im nächsten Beispiel möchte ich kurz erklären, wie man das ändern kann.
Außerdem fände ich einen Punkt in der Mitte der Uhr schön sowie den Stunden Zeiger nur halb so lang anzuzeigen, als den Sekundenzeiger, damit man diesen schneller erkennt.
Außerdem möchte ich das HTML vom CSS trennen und separat speichern. Das macht es einfacher etwas zu ändern und man behält besser den Überblick.
Bestimmt gibt es auch noch andere Dinge die man verbessern kann. Schaut einfach regelmäßg vorbei. Bald stelle ich euch diese Uhr vor.