Analog-Uhr mit Canvas


Analog-Uhr mit Canvas

◀  Diese Grafik wurde von einem Programm in der Programmiersprache → Javascript berechnet und in ein HTML Canvas-Element gemalt. Sie wird in Intervallen von je 1 Sekunde neu berechnet und gemalt.
Als Nachweis der Live-Herstellung dient die aktuelle Zeit, die analog dargestellt wird.

Das Javascript-Programm wird Live an ihrem Arbeits-PC ausgeführt.
Eine Animation erfordert hohe Rechenleistung in so kurzer Zeit, dass die laufende Berechnung an einem entfernten (Server)-PC und der Transport der Daten unwirtschaftlich oder sogar zu langsam wäre.

Die Grafik ist (von hinten nach vorne) aus 17 Elementen zusammengesetzt:
Kreisscheibe (Hintergrund) mit Rand, 12 Stunden-Markierungen, 3 Zeiger, Mittelpunkt.
Für Pixel-Grafik wird hier das Wort 'Malen' verwendet, um sie von → Objekt-Grafik ('Zeichnen') zu unterscheiden.


Für diese Demonstration wurde das Beispiel in eine Mini-Webseite eingebettet: Die Analog-Uhr lässt sich dann mehrfach verwenden und man kann den Quelltext ohne den störenden Overhead dieser Webseite anzeigen:

Mit diesem Link wird die ↗ Mini-Webseite mit Canvas-Grafik in einem eigenen Browser-Tab geladen.

Mit diesem Link wird der ↗ Quelltext der Mini-Webseite angezeigt: Aus diesem Text hat ihr Browser die Grafik + Animation hergestellt.


Die einfachste Version erzeugt eine (statische) Grafik fixer Größe. Damit wird die Canvas-Technologie in kompakter Form demonstriert.
Die dynamische Javascript-Version demonstriert moderne interaktive Technologie. Sie bietet maximale Sicherheit und Geschwindigkeit, weil alle Arbeiten am eigenen Arbeits-PC ausgeführt werden.
Die dynamische PHP-Version demonstriert klassische interaktive Technologie. Sie ist heute überholt, weil sie den Server unnötig belastet.

HTML



Das <canvas>-Element sollte alle 3 hier angegebenen Attribute enthalten:

Das id-Attribut muss eindeutig sein und dient zur Identifikation des Elerments mit Javascript.

Die Größe in Bildpunkten (Pixeln) sollte mit den Attributen width und height programmiert werden.


Formatierung mit CSS

Man kann Canvas-Elemente mit → CSS formatieren, z.B. mit den Eigenschaften border, float, margin, etc.

Die Angabe des Hintergrunds ist möglich, aber nicht sinnvoll: Er wird besser mit Javascript Canvas-Anweisungen programmiert.

Die Angabe der CSS-Eigenschaften Breite und Höhe (width, height) ist möglich, derzeit jedoch nicht zuverlässig: Verwenden sie dazu die gleichnamigen Attribute, so wie im Beispiel gezeigt.



Man kann prinzipiell jede mit Canvas erzeugte Grafik mit RechtsKlick als Datei canvas.png herunterladen. Das funktioniert unabhängig davon, ob sie direkt in einer Webseite enthalten ist oder (so wie hier) als eigenständiges Objekt eingebettet.

Die hier verwendeten Mini-Webseiten bieten zusätzlich die Möglichkeit, auch die Programme zur Erzeugung, Animation und Steuerung herunterzuladen:
Laden sie den Quelltext mit dem jeweils zur Verfügung gestellten Link, schalten sie die Zeilen-Nummern mit Mausklick ab und speichern sie den Quelltext in einer Text-Datei *.html am eigenen Arbeits-PC.
Diese Datei lässt sich mit jedem Browser öffnen und wird inklusive Animation angezeigt.

Programmierung von Canvas-Grafik mit Javascript


Canvas-Grafik wird Live gemalt. Die Methode eignet sich daher gut für Animationen (so wie das Beispiel dieser Seite) oder für interaktiv erstellte Grafik.

Normalerweise ist es sinnvoll, eine statische (gleichbleibende) Grafik in einer → Grafik-Datei zu verwalten. Wenn die Grafik jedoch mit wenig Aufwand programmierbar ist, dann kann man sie alternativ mit Canvas malen:
Canvas ist um Größenordnungen schneller als der Transport einer Grafik-Datei vom Webserver zum eigenen Arbeits-PC.


HTML + Javascript-Quelltext

 Aus diesem Quelltext hat ihr Browser die Canvas-Grafik hergestellt (und berechnet sie weiterhin jede Sekunde neu).
Das Beispiel befindet sich in einer eigenen Mini-Webseite ohne störenden Overhead. Diese Version erzeugt eine Grafik fixer Größe (200px).

Mit diesem Link wird die ↗ Mini-Webseite mit Canvas-Grafik in einem eigenen Browser-Tab geladen.

Mit diesem Link wird der ↗ Quelltext der Mini-Webseite angezeigt: Aus diesem Text hat ihr Browser die Grafik + Animation hergestellt.

Der winzige HTML <body>-Teil (am Ende des Quelltextes) enthält nur das <canvas>-Element.

Die gleichbleibenden Teile der Grafik (Hintergrund, Stunden-Striche) werden nur 1mal mit dem Javascript-Programm paint_once() gemalt.

Das Programm paint() ladet den Hintergrund und malt darüber die 3 Zeiger. Dieses Programm gibt zuletzt mit Methode setTimeout() die Anweisung, sich selbst nach 1000ms = 1 Sekunde erneut auszuführen.

Man kann den Quelltext in einer Datei *.html am eigenen PC speichern (Zeilen-Nummern vorher mit Klick abschalten): Die Datei lässt sich mit jedem Browser öffnen und zeigt die Grafik + Animation an.



Mit Methode translate() wird der Ursprung des Koordinaten-Systems in den Mittelpunkt der Grafik verschoben. Das erleichtert die Berechnung: Man sollte in jeder Grafik-Aufgabe den Ursprung so wählen, dass die Rechnungen einfach und übersichtlich werden.

Nun folgen die Grafik-Anweisungen für die einzelnen Elemente. Jede Grafik wird von hinten nach vorne aufgebaut: Später programmierte Objekte überdecken dann die vorher programmierten ohne weitere Maßnahmen.

Das Programm ist dazu ausgelegt, eine Grafik in einstellbarer Größe herzustellen. Die gewünschte Seitenlänge wird in der globalen Variablen size am Anfang des Javascript-Codes festgelegt.
Die Dimensionen aller Elemente, aber auch andere Eigenschaften (z.B. Strich-Stärke) werden aus dieser Variablen berechnet.


Stunden-Striche
Zuerst werden die Eigenschaften (strokeStyle, lineWidth) eingestellt.
Die for-Schleife wird 12mal durchlaufen. In jeder Schleife wird 1 Strich gemalt: Die Linie wird mit beginPath() begonnen, von moveTo() bis lineTo() definiert und mit stroke() gemalt. Danach wird die ganze Grafik mit rotate() um 1 Stunden-Winkel (360°/12=30°=Pi/6) gedreht.


Alle geltenden Regeln (hier z.B. die Lage des Mittelpunkts) werden mit Methode save() gespeichert.
Danach wird die Funktion paint() erstmals aufgerufen.



Die Funktion malt die 3 Zeiger und den Mittelpunkt.
Jedes dieser Elemente wird in 3 Phasen gemalt:
Festlegung der Eigenschaften (strokeStyle, lineWidth).
Definition der Linie mit beginPath(), moveTo(), lineTo()
Malen der Linie mit Methode stroke()


In diesem Beispiel wurde eine andere Methode gewählt: Die Linien werden direkt zu ihren Endpunkten gezogen. Damit erspart man das Speichern, Drehen und Wiederherstellen des gesamten Koordinaten-Systems.

Die wiederholt notwendige  Koordinaten-Transformation Polar → Cartesisch ist in die Funktion xy() ausgelagert. Sie gibt die beiden Koordinaten als Eigenschaften eines Objekts zurück. Die Winkelfunktionen (sin, cos) erwarten Argumente im Bogenmaß.


Mit Methode setTimeout() wird ein Timeout-Ereignis (Event) nach 1000ms = 1 Sekunde programmiert, mit dem die gleiche Funktion nochmals ausgeführt wird.

Interaktive Steuerung mit Javascript


Das Programm reagiert wesentlich schneller, weil seine Ausführung am eigenen Arbeits-PC meist um mehrere Größenordnungen weniger Zeit braucht ist als ein erneuter Download vom Server.

Der Server wird umso mehr entlastet, je öfter eine Grafik im Durchschnitt interaktiv geändert wird. Die höhere Geschwindigkeit des Servers wirkt sich auf alle BesucherInnen aus, auch wenn diese die interaktive Grafik nicht selbst laden.

Der Betrieb des Servers wird sicherer, weil die Möglichkeit der Manipulation eines (schlampig programmierten) PHP-Programms wegfällt.


Steuerung mit HTML-Formular

Ein Formular bietet die Möglichkeit, die Grafik mit klassischen Methoden zu steuern. Man kann auch eine traditionell mit PHP erzeugte Grafik ohne sichtbare Änderung durch eine mit Javascript+Canvas erzeugte ersetzen.

Hier werden die Formular-Elemente bei jeder Änderung mit → Javascript-Programmen gelesen und ausgewertet. Das ist notwendig, weil ein einfaches HTML-Formular die Werte der Options-Schalter und des → Schiebereglers nicht synchronisieren kann.

Mit diesem Link wird die ↗ Canvas-Grafik in einem eigenen Browser-Tab geladen. Dabei wird der Text ?size=400 an die Web-Adresse der Mini-Webseite angehängt. Sie können den Wert manuell ändern und die Seite mit der return-Taste erneut anfordern.


Direkte Steuerung

Ein Dokument, welches Canvas-Grafik erzeugt, muss dazu ohnehin Javascript-Programme enthalten. Mit wenig Aufwand kann man diese so modifizieren, dass sie sich auch von einem anderen Dokument fern-steuern lassen.

Die Bedienung ist hier weniger bequem als mit Formular-Elementen, das Beispiel dient jedoch zur Demonstration der Methode. Dazu sind keine (!) Javascript-Programme in der steuernden Webseite (=in dieser Seite) erforderlich. Man muss lediglich im HTML Hyperlink <a>-Element als Verweis-Ziel den Namen des Dokuments angeben.

Fortgeschrittene EntwicklerInnen sollten den Unterschied zwischen den beiden Methoden der Steuerung erkennen. Für alle anderen genügt es zu wissen, dass man eine Canvas-Grafik mit Programmen animieren und interaktiv steuern kann.
Mit diesem Link wird der ↗ Quelltext der Mini-Webseite angezeigt. In beiden Beispielen dieses Kapitels wird die gleiche Mini-Webseite verwendet !


Das HTML-Formular sieht vereinfacht so aus:
<form action="clock.html" method="get" target="uhr" onchange="this.submit()">
<input type="radio" name="rb1" value="100" />
<input type="radio" name="rb1" value="200" />
</form>
Die Formular-Daten werden bei jeder Änderung an das Ziel-Dokument clock.html gesendet. Damit wird jedoch nicht die aktuelle Webseite ersetzt sondern den Inhalt des als target angegebenen Innenrahmens uhr

Wenn sich das Formular in der gleichen Webseite wie die Canvas-Grafik befindet, dann entfällt das Attribut target und als Wert des Attributs action wird der Name einer Javascript-Funktion eingetragen, welche die → Formular-Daten liest und damit die Grafik ändert.


Die Decodierung der → GET-Argumente ist in 2 Funktionen geteilt. Der allgemeine Teil get_arguments_decode() braucht nur wenige Zeilen und ist für beliebige GET-Argumente verwendbar:
function get_arguments_decode() {
var arga,n,nva,qs,v;
qs = location.href.match(/\?(.*)/);
arga = RegExp.$1.split('&');
for(i=0; i<arga.length; i++) {
nva = arga[i].split('=');
n = nva[0].toLowerCase(); // Argument name
v = nva[1]; // Argument value
// Spezielle Decodierung
if(n=='size') {size_process(v);}
}
}
Die Details ( Reguläre Ausdrücke) erfordern zum Verständnis fortgeschrittene Kenntnisse.
Der spezielle Teil verarbeitet einen neuen Wert von size, falls dieser in den GET-Argumenten enthalten ist:
function size_process(v) {
size = parseInt(v);
}
In der Praxis braucht man meist eine eigene Funktion für jedes GET-Argument, welche angibt, was mit dem erhaltenen Wert geschehen soll.


Die Grafik lässt sich nun mit einem einfachen HTML <a>-Hyperlink steuern, z.B. vom übergeordneten parent-Dokument (hier: von der angezeigten Webseite):
<a href="javascript:do_reset(123)" target="uhr">
123 Pixel
</a>
Wenn der Link direkt im gleichen Dokument enthalten ist, welches die Canvas-Grafik erzeugt, dann entfällt das target-Attribut:
<a href="javascript:do_reset(234)">
234 Pixel
</a>

Zusammenfassung:

Hier wird ein Programm zur Live-Herstellung einer Canvas Pixel-Grafik vorgestellt.
Die Grafik kann wahlweise mit 2 verschiedenen Methoden gesteuert werden:
  • Mit einem HTML-Formular
  • Durch direkten Aufruf der steuernden Javascript-Funktion

Erzeugung & Steuerung von Pixel-Grafik mit PHP


Diese Grafik sieht zwar ähnlich aus, wurde jedoch mit einer ganz anderen Technologie erzeugt.
Die Pixel-Grafik wurde Live von einem Programm der Programmiersprache → PHP am Server-PC (!) erzeugt und so wie jede andere Grafik-Datei als Strom von binären Daten an ihren Browser gesendet.
Man kann die Grafik - so wie jedes andere Bild - mit RechtsKlick als Datei *.png auf den eigenen Arbeits-PC herunterladen.

Mit diesem Link wird die ↗ Grafik in einem eigenen Browser-Tab geladen. Sie enthält binäre (nicht lesbare) Daten, daher kann man keinen Quelltext der Grafik anzeigen.
Mit diesem Link wird der ↗ PHP-Quelltext des PHP-Programms angezeigt. Das ist für ein PHP-Programm normalerweise nicht möglich und wird hier ausnahmsweise (!) mit einem eigens dazu hergestellten Programm angezeigt.


Wenn man Pixel-Grafik mit PHP erzeugen will, dann braucht man
  • Einen Server-PC. Ideal geeignet ist ein → Virtueller PC mit Webserver (z.B. Apache oder Lighttp). Man entwickelt am eigenen Entwicklungs-Server und ladet nur fertige funktionierende Dokumente auf den Server des Web-Providers.
  • Der Webserver muss mit PHP zusammenarbeiten: Auf Linux verwendet man z.B. das Apache-PHP-Modul.
  • Das PHP GD-Modul muss entweder bereits fertig eingebaut (compiliert) sein, oder es muss bei Anforderung verfügbar sein.

Beispiele zur → Live-Erzeugung von dynamischer Pixel-Grafik mit PHP.


Nachteile

Die PHP-Version ist bei Wiederholung (= bei interaktiver Steuerung) deutlich langsamer als die Canvas-Version. Das liegt nicht am Server, sondern an der meist um einige Größenordnungen längeren Zeit für den Transport der Grafik vom Server zum Client (Arbeits-PC).

Eine Animation mit PHP ist zwar technisch möglich, jedoch sehr unwirtschaftlich. Dazu wäre es nötig, laufend neue Grafik-Dokumente am Server zu erzeugen und an die Clients zu senden.

Die Belastung des Server-PC ist ungleich größer. Jede einzelne am Server erzeuge Grafik verlängert die Antwort-Zeiten - und zwar auch für Clients, welche diese Grafiken gar nicht verwenden.

Die Sicherheit des Servers ist durch schlechte PHP-Programme gefährdet. Hacker können eine HTTP-GET-Anforderung sehr einfach manipulieren und damit schädlichen Code zum Server senden. Gute PHP-Programme übernehmen die GET-Argumente daher nur nach sorgfältiger Prüfung.

PHP läuft nur auf einem Server, nicht an einem Arbeits-PC. Man kann PHP+GD daher weder auf einem billigen Server ohne PHP noch direkt am eigenen PC ausführen.
Davon ist auch die Ausbildung betroffen: Zur Programmierung von Javascript+Canvas genügt im Notfall ein einfacher und auf jedem PC sofort verfügbarer Text-Editor, für PHP+GD braucht man Zugang zu einem Webserver mit PHP und GD-Modul.