XHTML SVG CSS PHP

Dr. O. Hoffmann

SVG- und PHP-Labor

Eins, zwei, drei im Sauseschritt
eilt die Zeit - wir eilen mit.
Wilhelm Busch

Analoge und digitale Uhren mit SVG

PHP kann oft recht hilfreich eingesetzt werden, um mit Schleifen einfache Strukturen auszurechnen, aber auch um dynamische Prozesse zu initialisieren.
Eine analoge oder digitale SVG-Uhr (auch: Analoguhr beziehungsweise Digitaluhr) ist da ein schönes Übungsbeispiel, welches von überschaubarem Ausmaß ist. Zwar gibt es mit ecma-script oder java-script auch andere Methoden, um ähnliche Aufgaben zu erledigen, diese haben jedoch den Nachteil, daß sie nicht zuverlässig sind, da sie nutzerseitig ablaufen, während PHP serverseitig abläuft und somit nicht von dem Eigenschaften des Darstellungsprogrammes abhängt. Daten wie die Zeit des servers sind zudem so zugänglich, während mit nutzerseitigen Skripten ähnliche Daten des Nutzerrechners zum Einsatz kommen.
Bei der geplanten Uhr wird also entweder eine vom Nutzer vorgegebene Zeit genommen werden oder die Zeit des servers. Andere Autoren haben auch bereits SVG-Uhren mit nutzerseitigen Skripten realisiert, die somit deren Zeit anzeigen - die die entsprechenden Nutzer ja vermutlich selbst besser kennen werden.

Das Ziel ist also erst einmal, eine analoge Uhr zu erstellen, die irgendwie auf die richtige Zeit gestellt ist. Weil das Stellen mit SVG allein entweder nicht ganz einfach ist oder dabei oft Mängel der aktuellen Darstellungsprogramme zum Vorschein kommen, ist die Verwendung von PHP zuverlässiger, bindet die Uhr aber jedenfalls immer an den server.

Als Grundgerüst werden zunächst ein paar Eingaben von GET-Parametern zur Größe der Uhr x die Breite, y die Höhe und m als Maßeinheit (px, %, cm, mm) und der Eingabe der Anfangszeit in der Form hh:mm:ss mit hh der Stundenangabe, mm der Minuteneingabe und ss der Sekundeneingabe angelegt.
Als nächstes wird ein header für das SVG-Format gesendet und dann kommt schon das Grundgerüst der SVG-Datei mit Titel, Kurzbeschreibung, zwei Rechtecken für Hintergrundfarbe und Rahmen und etwas Text als Signatur. Durch Einsatz des viewBox-Attributes im svg-Element wird der Inhalt unabhängig von den von außen vorgebbaren Abmessungen der Uhr.
Analoge SVG-Uhr, Vorbereitung (Quelltext analoge SVG-Uhr, Vorbereitung).

Der nächste Schritt ist die Erstellung der typischen Skalen einer runden Uhr. Das wird mit einigen Schleifen erreicht. Einmal ausgerechnet, könnte der statische Quelltext auch abgespeichert werden, um ihn nicht jedesmal neu berechnen zu lassen, das würde den server etwas entlasten, vergrößert aber die abgespeicherte Datei.
Analoge SVG-Uhr, erster Schritt (Quelltext analoge SVG-Uhr, erster Schritt).

Etwas eleganter und präziser und auch noch mit der Hand erstellbar werden die Skalen, wenn in SVG gedreht wird und nicht in PHP: Analoge SVG-Uhr, erster Schritt, Alternative (Quelltext analoge SVG-Uhr, erster Schritt, Alternative).

Nun werden die Zeiger der Uhr ergänzt - das sind erstmal einfache Striche. Da diese sich zeitlich drehen sollen, werden sie von einem animierten g-Element umschlossen. Was in XHTML das div-Element ist, ist in SVG gewissermaßen das g-Element.

Nun sind 12 Stunden genau 43200s - die im dur-Attribut angegebene Dauer für eine ganze Drehung. Ein mir immer noch unverstandenes Phänomen ist die 12-Stundenskala statt einer 24-Stundenskala, weil ja nunmal ein Tag 24 Stunden hat und nicht 12 - aber lassen wir das hier an dieser Stelle. 3600s ist die Umlaufzeit für den Minutenzeiger - also eine Stunde. Bleiben dann natürlich 60s für die Umlaufzeit des Sekundenzeigers.
Analoge SVG-Uhr, zweiter Schritt (Quelltext analoge SVG-Uhr, zweiter Schritt).

Bislang ist die Uhr noch gar nicht auf die aktuelle Zeit eingestellt - sie wird also nur zweimal am Tag richtig gestellt sein. Auf einen solchen Zeitpunkt mögen natürlich nur wenige warten. Zum ersten Mal wird nun PHP ernsthaft gebraucht, um die aktuelle server-Zeit in Erfahrung zu bringen. Damit wird die Uhr gestellt, indem die Zeiger wie im richtigen Leben in die richtige Position gedreht werden, wozu abermals ein g-Element verwendet wird. Zwar könnte auch das jeweils bereits vorhandene verwendet werden, im Sinne einer Aufgabentrennung sieht das so aber übersichtlicher aus. Das mit einem g-Element zu erreichen, bleibt dem Leser zur Übung überlassen. Ebenso eine gegebenenfalls notwendige Zeitzonenkorrektur, wenn die Uhrzeit gegenüber der des web-servers verschoben sein soll.
Analoge SVG-Uhr, dritter Schritt (Quelltext analoge SVG-Uhr, dritter Schritt).

Eingangs angelegt wurde ja auch noch die Möglichkeit, die Startzeit als GET-Parameter einzugeben, dies wird nun berücksichtigt mit einfachen if-Abfragen. Die Perfektionierung der Kontrolle der Nutzereingabe bleibt ebenfalls dem Leser zur Übung überlassen. Hier vorgegeben: zeit=12:34:56, zum Testen einfach in der URI ändern.
Analoge SVG-Uhr, vierter Schritt (Quelltext analoge SVG-Uhr, vierter Schritt).

Sofern das Darstellungsprogramm mitspielt, geht es natürlich auch noch einfacher mit dem Stellen der Uhr. Dann wird nicht unbedingt PHP gebraucht. Dazu hat SVG den überaus praktischen wallclock-Wert für das begin-Attribut. Damit kann die Uhrzeit einfach gestellt werden. Weder PHP noch sonst eine Programmier- oder Skriptsprache sind dazu notwendig, schlichtes SVG 1.1 tiny reicht aus:
Analoge SVG-Uhr mit aktueller UTC (Quelltext analoge SVG-Uhr, mit aktueller UTC).
Analoge SVG-Uhr mit aktueller lokaler Zeit des Nutzers (Quelltext analoge SVG-Uhr, mit aktueller lokaler Zeit des Nutzers).

Wenn das nicht geht, bleibt die Überlegung, wie die Uhr wenigstens manuell gestellt werden kann. Dies funktioniert in SVG mit entsprechend schnelleren Animationen, die mittels Interaktion angesprochen werden können:
Manuell stellbare analoge SVG-Uhr (Quelltext manuell stellbare analoge SVG-Uhr).
Die Uhr wird mittels der Knöpfe S (schnell), N (normal), L (langsam) gestellt, starten geht mit mousedown, stoppen mit mouseup. Mit dem Startknopf wird die normale Uhr gestartet.

Eine Digitaluhr kann über das Austauschen von Inhalten recht einfach erreicht werden - hat mich einiges Grübeln gekostet, bis ich das verstanden hatte. Dazu wird etwa von einem use-Element oder tref-Element das xlink:href-Attribut animiert - zuvor hat man in einem defs-Bereich die Zahlen von 0 bis 9 als Text abgelegt. Beispiele ohne das Stellen der digitalen Uhr, welches ja bereits hier erläutert wurde, gibt es unter dem Menüpunkt Vektorgraphik - Animation.
Digitale SVG-Uhr mit lokaler Zeit (Quelltext digitale SVG-Uhr mit lokaler Zeit).
Entsprechend dazu eine
Digitale SVG-Uhr, Zeit mit PHP gestellt (Quelltext digitale SVG-Uhr, Zeit mit PHP gestellt).

Will man etwa zu Silvester rückwärts zählen, tauscht man einfach die Reihenfolge der Animationswerte:
Silvesteruhr, Zeit mit PHP gestellt (Quelltext Silvesteruhr, Zeit mit PHP gestellt).
Bei einer analogen Uhr könnte man entsprechend einfach die Ziffern rückwärts auftragen. Man kann sie auch so lassen, dann muß man aber die Zeiger an der vertikalen Achse (von der 12 zur 6) spiegeln. Eventuell sollte man dann aber doch die 12 gegen eine 0 tauschen.

Das manuelle Stellen ist bei nicht gleichmäßig laufenden Uhrwerken wie auch digitalen Uhren etwas komplizierter oder umfangreicher, weil es nicht reicht, die Stunden, Minuten und Sekunden unabhängig voneinander einzustellen, was einfach ist. Das Problem liegt darin, die Animation dann so laufen zu lassen, daß Stunden und Minuten jeweils exakt zum richtigen Zeitpunkt wechseln. Eine Möglichkeit besteht darin, die Sekunden nur auf 0 einstellbar zu lassen und nur die volle Stunde oder nur jede Viertelstunde und dann jeweils für jede Viertelstunde eine andere Animation anzulegen. Ist dann allerdings nichts für ungeduldige Mitmenschen. Wird die Uhr hingegen mit der Hilfe von PHP gestellt, ergibt sich dies Problem nicht und es ist lediglich ein korrekter Start zu erstellen.
Für SVG ist allerdings auch ein Modul in Vorbereitung, bei dem Parameter an eine Datei übergeben werden können, damit sollte sich auch die manuelle Einstellung per PHP in Zukunft ersetzen lassen.

Eine andere Idee ist, Ziffern als Pfade, Glyphen oder aus einzelnen Strichen zu konstruieren und sie dann entweder diskret oder kontinuierlich animierend ineinander zu transformieren. Das erfordert aber etwas genauere Studien und etwas Programmier- und Denkarbeit. In jedem Falle ist für keinen der beiden Uhrtypen java-script oder ecma-script notwendig. Eine normale deklarative Animation funktioniert bei deutlich mehr Darstellungsprogrammen als eine Animation per Skript, weswegen man auf letztere soweit möglich verzichten sollte.

Stattdessen ist es unterhaltsamer zu gucken, wie die Uhr noch etwas dekoriert werden kann - Zeiger austauschen, das Springen des Sekundenzeigers einiger Uhren simulieren und sonst noch ein paar Spielereien einbauen. Die folgende Deko-Uhr hat es da schon in sich - besonders der animierte Gradient als Hintergrund hat das Potential, ältere langsame Prozessoren in die Knie zu zwingen ;o)
Analoge SVG-Uhr, Dekoration
(Quelltext analoge SVG-Uhr, Dekoration)

Alternativ dazu eine Mischung aus analoger und digitaler Uhr, eine, bei der die Zeiger etwas federnd in eine neue Position springen:
SVG-Uhr mit Dekoration
(Quelltext SVG-Uhr mit Dekoration)
Dafür oder außerdem wird bei diesem Beispiel kumulative Animation verwendet und auch spline-Interpolation. Die präzisen Zeiten für das Springen der Zeiger werden mit negativen Zeiten für begin eingestellt.

Als weitere Variation hier eine Analoge 24-Stunden-Uhr
(Quelltext Analoge 24-Stunden-Uhr). Das Uhrwerk funktioniert ähnlich wie bei der vorherigen Uhr. 0 Uhr ist nur horizontal rechts.

Der Haken solcher Uhren ist natürlich, daß der Nutzer die Animation jederzeit unterbrechen kann. Die Fortsetzung der Animation hat dann natürlich eine falsche Uhrzeit zur Folge. Allerdings wird man nicht davon ausgehen, daß solch eine Uhr wirklich über längere Zeit genutzt werden wird. Die Genauigkeit der Uhr wiederum hängt nur am Darstellungsprogramm des Nutzers und wird nie wieder mit dem server synchronisiert. Vermutlich wird das Darstellungsprogramm zur Synchronisation den Quarzoszillator im Rechner des Nutzers verwenden. Erfahrungsgemäß kann bei üblichen Quarzoszillatoren mit einer relativen Genauigkeit besser als 10-5 gerechnet werden.
Nun könnte mittels PHP auch auf Zeitsignale der PTB zurückgegriffen werden, um die Uhr zu stellen, da sollte zwar die Genauigkeit besser als 10-13 sein, wegen fehlender Synchonisation hat man da aber nicht viel von. Bei einem server sollte man ohnehin davon ausgehen, daß dieser über NTP synchronisiert wird, so daß sich der Autor eines PHP-Skriptes darauf verlassen kann, statt nach eigenen Lösungen zu suchen.