11.2 Animierte JPEGs  
Sie kennen sicherlich die Basis aller nervenden Werbebanner im World Wide Web – animierte GIF-Grafiken. Als das Grafikformat 1987 bzw. 1989 im Auftrag der Firma CompuServe entwickelt wurde, dachte noch niemand daran, dass dieses geheime Feature – nämlich die Integration mehrerer Einzelgrafiken in eine GIF-Datei – später einmal Furore machen sollte. Leider ist das nur mit GIF-Grafiken möglich, die ja auf nur 256 Farben beschränkt sind. Fotorealistische Animationen sind damit nicht oder nur in sehr schlechter Qualität möglich. Dafür wären die Formate JPEG und PNG besser geeignet, wenn sie denn Animationen unterstützen würden (was sie nicht tun).
Mit JavaScript kann dieser Missstand behoben werden, und zwar mit dem Image-Objekt. Nach Ablauf einer bestimmten Zeitdauer wird einfach das nächste Bild der Animation eingeblendet. Im Folgenden finden Sie den Code, der die Animation mit einer Verzögerung von einer Sekunde zwischen den Einzelbildern auf den Bildschirm bringt:
<html>
<head>
<title>JPEG-Animation</title>
</head>
<script text="type/javascript"><!--
var bilder = new Array("ani1.jpg", "ani2.jpg",
"ani3.jpg", "ani4.jpg");
var naechstesBild = 0; //Index des nächsten Bildes
var verzoegerung = 1000; //Verzögerung in Millisekunden
function animation() {
document.ani.src = bilder[naechstesBild];
naechstesBild++;
if (naechstesBild==bilder.length) {
naechstesBild = 0;
}
setTimeout("animation();", verzoegerung);
}
//--></script>
</head>
<body onload="animation();">
<h3>Animation</h3>
<img src="ani1.jpg" name="ani" />
</body>
</html>
11.2.1 Eine Animation mit JavaScript  
Für das Skript werden ein paar globale Variablen benötigt:
var bilder = new Array("ani1.jpg", "ani2.jpg", "ani3.jpg", "ani4.jpg");
var naechstesBild = 0; //Index des nächsten Bildes
var verzoegerung = 1000; //Verzögerung in Millisekunden
In dem Array bilder stehen die Dateinamen der einzelnen Grafiken der JPEG-Animation. In der Variablen naechstesBild wird der Array-Index des nächsten Bildes der Animation gespeichert. Angefangen wird beim ersten Bild. Es besitzt den Index 0, also enthält die Variable den Startwert 0. Die letzte Variable, die die Verzögerung in Millisekunden zwischen den einzelnen Animationsschritten enthält, müsste eigentlich nicht als global deklariert werden. Behalten Sie aber immer im Hinterkopf, dass Ihre Skripten von Leuten bearbeitet werden könnten, die sich nicht so gut in JavaScript auskennen. In so einem Fall ist es gut, wenn wichtige Parameter für das Skript an markanter Stelle stehen, so dass dort auch unbedarftere Kollegen Änderungen vornehmen können, ohne gleich den gesamten Programmcode zu ruinieren.
Jetzt fehlt nur noch die Funktion animation(), die das nächste Bild der Animation anzeigt (der Index wird aus der Variablen naechstesBild gewonnen) und sich selbst nach einiger Zeit (diese steht in verzoegerung) wieder aufruft. Davor muss natürlich noch die Nummer des nächsten Bildes um eins erhöht werden. Sollte man beim letzten Bild angekommen sein, soll die Animation wieder von vorn beginnen; naechstesBild wird also auf 0 gesetzt.
function animation() {
document.ani.src = bilder[naechstesBild];
naechstesBild++;
if (naechstesBild==bilder.length) {
naechstesBild = 0;
}
setTimeout("animation()", verzoegerung);
}
Nun fehlt nur noch ein Punkt: die Funktion animation() muss erst einmal aufgerufen werden – beispielsweise mit dem onload-Event-Handler des <body>-Tags:
<body onload="animation();">
11.2.2 Bilder in den Cache laden  
Wenn Sie dieses oder das letzte Beispiel auf der heimischen Festplatte oder auf dem lokalen Webserver ausprobieren, funktioniert alles wunderbar. Sobald Sie die Seiten aber in das World Wide Web stellen, werden Sie wahrscheinlich eine böse Überraschung erleben: Es dauert unter Umständen mehrere Sekunden, bis die neue Grafik erscheint. Der Grund dafür ist schnell gefunden: Die neuen Grafiken müssen ja erst einmal vom Browser angefordert und über das Internet übertragen werden. Je nach Qualität der Verbindung kann das schon seine Zeit dauern. Zwar können Sie mit JavaScript die Ladegeschwindigkeit des Browsers nicht verbessern, aber Sie können wenigstens so tun. Ist eine Grafik nämlich einmal geladen, so liegt sie im Speicher- oder Festplattencache des Browsers. Der Trick ist nun, die Grafiken nicht erst zu laden, wenn sie angezeigt werden sollen, sondern schon vorher. Das ist sogar in HTML möglich, man muss nur darauf achten, dass die Grafiken nicht optisch stören. Der erste Versuch, Höhe und Breite der Grafik auf 0 zu setzen, schlägt fehl, da die meisten Browser das ignorieren. Also muss man das nächstkleinere Maß nehmen: 1 × 1 Pixel.
<img src="ani2.jpg" width="1" height="1" />
<img src="ani3.jpg" width="1" height="1" />
<img src="ani4.jpg" width="1" height="1" />
Wollen Sie komplett vermeiden, dass die Grafiken sichtbar oder erahnbar sind, müssen Sie in die JavaScript-Trickkiste greifen. Das Image-Objekt hilft Ihnen hierbei. Mit dem folgenden Befehl wird ein Image-Objekt erzeugt, dessen src-Eigenschaft auf "ani2.jpg" gesetzt wird. Der besondere Effekt hierbei: Die Grafik wird vom Browser im Hintergrund geladen und liegt damit im Cache.
var img = new Image();
img.src = "ani2.jpg";
Wenn man ganz sauber programmieren will, gibt man dem Konstruktor des Image-Objekts noch die Breite und Höhe der Grafik mit, was aber in der Praxis überhaupt keine Auswirkungen hat:
var img = new Image(breite, hoehe);
img.src = "ani2.jpg";
Die Instanz des Image-Objekts befindet sich nun im Speicher, und die Grafik wird vom Webserver angefordert, aber noch gar nicht angezeigt. Umgangssprachlich nennt man das Vorladen oder Preloading. Zuerst überarbeiten wir das Beispiel aus dem vorigen Abschnitt:
<html>
<head>
<title>Bildlein-Wechsle-Dich</title>
<script type="text/javascript"><!--
var img_over;
function preload() {
img_over = new Image();
img_over.src = "galileo_over.gif";
}
function over() {
document.grafik.src = img_over.src;
}
function out() {
document.grafik.src = "galileo_out.gif";
}
preload();
//--></script>
</head>
<body onload="onload();">
<a href="https://www.rheinwerk-verlag.de/?GPP=openbook">
<img src="galileo_out.gif" name="grafik"
onmouseover="over();" onmouseout="out();" />
</a>
</body>
</html>
Beim Laden des HTML-Dokuments wird die JavaScript-Funktion preload() aufgerufen, die die Grafik galileo_over.gif in den Cache des Browsers lädt. Die Grafik galileo_out.gif muss nicht extra geladen werden, sie wird ja im HTML-Dokument schon angezeigt.
Beachten Sie auch die folgende neue Zeile in der Funktion over():
document.grafik.src = img_over.src
Die src-Eigenschaft der Grafik mit dem name-Attribut "grafik" wird also auf die src-Eigenschaft der Variablen img_over gesetzt. Das bringt zwar in diesem Beispiel keine Vorteile, aber Sie sollten das Verfahren einmal gesehen haben. Wenn die Grafikabteilung Ihrer Firma mal wieder besonders kreative Dateinamen gewählt hat, kann dieses Vorgehen durchaus nützlich sein, da Sie dann wenigstens brauchbare Variablennamen vergeben können.
Die Animation kann ebenso schnell angepasst werden. Da aber schöner Code herauskommen soll, wird hier ein wenig mehr Aufwand getrieben. Die Namen und auch die URLs der einzelnen Grafiken sollen in Variablen gespeichert werden. Dies hat wieder den Vorteil, dass ein größerer Personenkreis das Skript bearbeiten kann, indem einfach die Werte der globalen Variablen geändert werden.
Im ersten Schritt soll eine Funktion geschrieben werden, die eine Reihe von Grafiken in den Cache lädt. Die URLs der Grafiken werden dabei als Parameter an die Funktion übergeben. Wie man die Anzahl der übergebenen Parameter ermittelt, ist einfach: NameDerFunktion.arguments. length. Der Rest ist schnell geschrieben:
function preload() {
var img;
for (var i=0; i<preload.arguments.length; i++) {
img = new Image();
i.src = preload.arguments[i];
}
}
Diese Funktion lädt alle übergebenen Grafiken in den Cache. Leider kann man nicht über den Variablennamen auf die Grafik zugreifen, da lediglich eine Variable verwendet wird. Ohne Fleiß kein Preis: In diesem Beispiel sollen die Image-Variablen für die Animation auch in einem Array gespeichert werden. Diese Variablen sollen auch von anderen Funktionen aus angesprochen werden können, müssen also als global definiert werden.
var bildvariablen = new Array();
function preload() {
var img
for (var i=0; i<preload.arguments.length; i++) {
img = new Image();
img.src = preload.arguments[i];
bildvariablen[i] = img;
}
}
Schließlich muss nur noch die Funktion animation() angepasst werden – hier wird auf die Variablen der Grafiken zugegriffen und nicht direkt auf deren URL.
function animation() {
document.ani.src = bildvariablen[naechstesBild];
naechstesBild++;
if (naechstesBild==bilder.length) {
naechstesBild = 0;
}
setTimeout("animation();", verzoegerung);
}
|