Die Erstellung von Animationen ist zweifelsohne eine der faszinierendsten Aufgaben eines Webdesigners. Grund genug, diesem Themen ein eigenes Kapitel zu widmen und Sie mit verschiedenen Techniken zur Erstellung von Animationen bekannt zu machen.
Die Grundform der Animation ist eine Folge von Bildern, die nacheinander angezeigt werden.
Für die Erstellung von Animationen mit bewegten Elementen gibt es wieder unterschiedliche Techniken:
In Webseiten kann man solche Animationen auf verschiedene Weisen einbinden:
Darüber hinaus erlaubt uns DHTML auch noch andere Formen der Animation, die darauf beruhen, dass man absolut positionierte HTML-Elemente via CSS-Positionierung und JavaScript verschieben kann. So kann man
Die folgenden Abschnitte sollen Ihnen einen kleinen Überblick geben und Sie in die wichtigsten Animationstechniken einführen.
GIF-Animationen sind Frame-Animationen, das heißt, eine Folge von Bildern wird Bild für Bild hintereinander abgespielt. Um GIF-Animationen erstellen zu können, braucht man
ImageMagick ist eine Sammlung von Konsolenprogrammen zur Grafikbearbeitung. Wegen der fehlenden grafischen Benutzeroberfläche ist die Bedienung etwas gewöhnungsbedürftig, aber dafür stehen die Programme kostenfrei für fast alle Plattformen zur Verfügung.
Die ImageMagick-Programmsammlung kann von www.simplesystems.org/ImageMagick heruntergeladen werden.
Nachdem Sie ImageMagick heruntergeladen und installiert haben (siehe begleitende Dokumentation), brauchen Sie nur noch in einem geeigneten Grafikprogramm die Bilder für die Frames zu erstellen, und schon kann es losgehen.
Für das folgende Beispiel verwenden wir drei Photos mit Ansichten amerikanischer Städte (siehe Abbildung 16.2).
Abbildung 16.2: Einzelne Frames für den Bilderwechsler
Die einzelnen Frames haben alle den gleichen Namen, plus einer Indexnummer. Für die Arbeit mit dem ImageMagick-Tool ist dies ganz wichtig. Um aus diesen drei Frames eine GIF-Animation zu machen, gehen Sie wie folgt vor:
> convert -loop 0 -delay 100 usa*.jpg usaAnim.gif
Das erste Argument, -loop 0, gibt an, wie oft die Animation wiederholt werden soll. Der Wert 0 steht hierbei für eine endlose Wiederholung.
Der zweite Argument, -delay 100, gibt an, wie viele Hundertstelsekunden jedes Bild angezeigt werden soll.
Das dritte Argument gibt die Frames an. usa*.jpg bewirkt, dass alle JPG-Bilder, deren Dateinamen mit usa anfängt und die im aktuellen Verzeichnis stehen, aufgenommen werden. Die Reihenfolge der Bilder in der Animation richtet sich nach der lexikographischen Reihenfolge ihrer Dateinamen (in unserem Beispiel also nach den auf das Präfix usa folgenden Nummern).
Schließlich geben wir noch den Namen der zu erzeugenden Animationsdatei an (hier usaAnim.gif).
Abbildung 16.3: Aufruf von convert
Die erzeugte GIF-Datei können wir in ein Verzeichnis auf dem Webserver kopieren und per <img>-Tag in eine Webseite einbinden:
<img src="usaAnim.gif" alt="Animation" />
Auf die gleiche Weise kann man mit Hilfe des convert-Tools zeichentrickähnliche Animationen, Übergänge oder Ähnliches erstellen.
Wer unter Windows arbeitet, kann zwischen einer Vielzahl von Shareware-Programmen zur Erstellung von GIF-Animationen wählen. Eines der populärsten und leistungsfähigsten ist der Ulead GIF-Animator. Von www.ulead.com können Sie sich eine Probeversion (Download/Trial-Link) herunterladen.
Sofern Sie die einzelnen Frames für die Animation bereits erstellt haben, ist die Erzeugung der GIF-Animationsdatei mit dem Ulead GIF-Animator kein Problem mehr.
Mit Ulead können Sie aber auch Animationen mit Sprites erzeugen.
Als Ausgangsmaterial für die folgende Animation dient uns die Kopf-Clipart aus dem vorangehenden Abschnitt und eine kleine selbstgezeichnete Fliege. In der GIF-Animation soll die Fliege um den Kopf herumfliegen.
Abbildung 16.5: Die Ausgangsbilder
Beide Bilder hätte man übrigens auch im Ulead GIF-Animator erstellen können, aber so können wir Ihnen die Bilder auf der Buch-CD zur Verfügung stellen.
Wichtig ist, dass der Frame mit dem größten Bild zuerst kommt. Dann interpretiert Ulead die kleineren Bilder nämlich als Sprites, die über das größere Bild bewegt werden.
Korrigieren Sie gegebenenfalls die Reihenfolge der Bilder, indem Sie den Frame eines Bildes im linken Arbeitsbereich anklicken und den markierten Frame dann mit Hilfe der Befehle Layer/Move Layer Up und Layer/Move Layer Down verschieben.
Wenn Sie einen Frame löschen wollen, markieren Sie ihn im linken Arbeitsbereichfenster und rufen Sie den Menübefehl Edit/Delete auf.
Nachdem Sie fliege.gif geladen haben, werden Sie unter Umständen enttäuscht sein, dass man die Fliege gar nicht erkennen kann, da der transparente Hintergrund der Fliege durch den globalen schwarzen Hintergrund ersetzt wird.
Abbildung 16.6: Bildhintergrund und globaler Hintergrund passen nicht
Sie können die Hintergrundfarbe auch über die Palette auswählen. Falls die Farbpalette nicht angezeigt wird, rufen Sie zuerst den Befehl View/Color Toolbar auf. Klicken Sie dann auf das Farbfeld neben dem Index-Feld für die Hintergrundfarbe. Wenn Sie jetzt die Maus über die Farbpalette bewegen, verwandelt sich der Mauszeiger in eine Pipette und Sie können eine Farbe durch Klick mit der Pipette auswählen.
Klicken Sie dann auf den Eintrag des kopf-Frames. Dieser verwendet per Voreinstellung keine transparente Farbe. Wenn Sie wollen, können Sie dem Frame aber über die Option Transparent index eine transparente Farbe zuweisen.
Klicken Sie zum Schluss noch einmal auf den fliege-Frame. Die Fliege sollte dank der Änderung der globalen Hintergrundfarbe jetzt gut zu erkennen sein.
Sie haben immer noch das fliege-Frame markiert. Klicken Sie jetzt im rechten Arbeitsbereich auf den Reiter Preview. Ulead spielt die Animation auf dem derzeitigen Arbeitsstand ab, das heißt, Sie müssten jetzt den Kopf mit einer blinkenden Fliege über der Nasenspitze sehen.
Beachten Sie, dass die Frames nicht mehr im Wechsel eingeblendet werden. Dies liegt daran, dass die Frames unterschiedliche Bildgrößen haben. Der erste Frame wird daher als Hintergrund verwendet.
Die Fliege soll vom linken Ohr (im Bild rechts) zum unteren Teil der Nase fliegen. Wir müssen die Fliege also auf ihre Ausgangspostion am linken Ohr verschieben.
Alternativ können Sie die Position auch über die Felder X-Offset und Y-Offset aus der Attribute-Werkzeugleiste setzen. Gute Werte sind X-Offset gleich 81 und Y-Offset gleich 35.
Als Nächstes wollen wir neun Kopien des Fliegen-Frames anlegen. In jedem dieser Frames soll die Fliege ein wenig weiter nach links geflogen sein, bis sie in der neunten Kopie unter der Nase angekommen ist.
Eine Möglichkeit, die neuen Frames zu erstellen, wäre, den fliege-Frame zu markieren, dann über die Zwischenablage (Befehle Edit/Copy und Edit/Paste Image) zu kopieren, neun Mal einzufügen und die Fliege in jedem Frame neu zu positionieren. Man kann sich diese Arbeit aber auch ein wenig erleichtern.
Abbildung 16.8: Sprite kopieren und verschieben
So wie die Animation jetzt konfiguriert ist, wird die Fliege auf jeder Position eingezeichnet und bleibt eingezeichnet. Damit die vorangehenden Positionen automatisch gelöscht werden, könnte man die fliegen-Frames zusammen markieren und ihnen im Feld How to remove die Option To Previous State zuweisen. Doch leider wird diese Option nicht von allen Browsern unterstützt. Besser ist es, wenn wir die einzelnen Sprites wieder mit dem Hintergrundbild zu normalen Frames verwandeln.
Den letzten Frame, in dem die Fliege halb über der Nase liegt, müssen wir von Hand ein wenig nachkorrigieren.
Vergrößern Sie das Bild gegebenenfalls durch Klick auf das Lupen-Symbol in der Werkzeugleiste.
Klicken Sie dann in das vordere Farbfeld unter der Werkzeugleiste. Dieses Farbfeld gibt die Vordergrundfarbe beim Zeichnen an. Nachdem Sie das Feld angeklickt haben, bewegen Sie die Maus über die Nase. Der Mauszeiger nimmt die Gestalt einer Pipette an. Klicken Sie jetzt in die Nase. Die Farbe der Nase wird als neue Vordergrundzeichenfarbe ausgewählt.
Klicken Sie jetzt in der Werkzeugleiste auf den Zeichenstift. Übermalen Sie den Teil der Fliege, der über die Nase ragt.
Jetzt sollte das Bild so aussehen, als würde die Fliege unter der Nase wegfliegen.
In der Attribute-Werkzeugleiste können Sie über die delay-Eigenschaft festlegen, wie lange der ausgewählte Frame angezeigt werden soll (in Hunderstel Sekunden). Sollen mehrere Frames die gleiche delay-Eigenschaft zugewiesen bekommen, kann man die Frames gemeinsam markieren (durch Gedrückthalten der (Strg)-Taste) und dann die delay-Eigenschaft einmal für alle markierten Frames einstellen.
Zum Abschluss der Animation brauchen wir noch einen Kopf ohne Fliege, der den Teil der Animation darstellt, in dem die Fliege hinter dem Kopf zurück zum Ohr fliegt.
Listing 16.1: fliegenAnim.html
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>GIF-Animation</title>
</head>
<body>
<h1>Mit Sprite erstellte Animation</h1>
<div style="margin-left: 100px">
<img src="fliegenAnim.gif" alt="Animation" />
</div>
</body>
</html>
Im Internet gibt es eine Vielzahl von Quellen für GIF-Animations-Software oder auch fertige und frei verfügbare GIF-Animationen. Starten Sie einfach Ihren Browser, steuern Sie eine Suchseite an (yahoo, lycos, fireball, etc.) und suchen Sie nach Begriffen wie GIF oder GIF-Animation.
Von DHTML, oder »dynamischem HTML«, sprechen wir, wenn wir mit JavaScript auf den HTML-Code einer Webseite zugreifen und so das Erscheinungsbild der Webseite beziehungsweise einzelner HTML-Elemente verändern. Von DHTML im engeren Sinne sprechen wir, wenn wir JavaScript mit HTML/CSS-Techniken zur Positionierung und Sichtbarkeitseinstellung von HTML-Elementen kombinieren.
Ein erstes Beispiel dazu haben Sie bereits in Abschnitt 10.7 bei der Implementierung dynamischer Listen gesehen. In diesem Abschnitt wollen wir Ihnen am Beispiel einer kleinen Hai-Animation weitere DHTML-Techniken vorstellen.
Obwohl wir in diesem Abschnitt eine zeichentrickähnliche Animation mit Bildern erstellen, ist die Animation mit Bildern keineswegs das einzige Einsatzgebiet für DHTML. Mit DHTML können Sie praktisch jedes beliebige Element einer Webseite verrücken, ausblenden, animieren.
Um mit JavaScript beliebige Animationen oder DHTML-Anwendungen aufsetzen zu können, sollten Sie mit folgenden Techniken vertraut sein:
Von all diesen Techniken fehlt uns nur noch die letzte.
Die einfachste Möglichkeit, einen Code mehrfach hintereinander auszuführen, besteht in der Implementierung einer Schleife. Für die Implementierung von Animationen mit JavaScript sind Schleifen aber üblicherweise nicht sinnvoll, weil es keine vernünftige Möglichkeit gibt, zwischen den einzelnen Schleifeniterationen Pausen von festgelegter Dauer einzurichten.
Hingegen bietet uns JavaScript die Möglichkeit, eine Funktion nach Ablauf einer bestimmten Zeitspanne aufzurufen - und zwar mit Hilfe von setTimeout().
setTimeout("eineFunktion()",200);
Die window-Methode setTimeout() übernimmt als Argumente den Namen einer JavaScript-Funktion und eine Zeitangabe in Millisekunden. Nach Ablauf dieser Zeitspanne wird die übergebene Funktion aufgerufen.
Nehmen wir nun an, wir wollten ein HTML-Element alle zwei Sekunden um zehn Pixel nach rechts bewegen. Um dies mit Hilfe von setTimeout() implementieren zu können, bedarf es eines kleinen Tricks: Man definiert eine Animations-Funktion, in der man das HTML-Element um zehn Pixel verrückt. Am Ende der Funktion ruft man setTimeout() mit 2000 (gleich 2 Sekunden) als zweitem und - jetzt kommt der Trick - der Animations- Funktion als erstem Argument auf.
function animFunk()
{
// Code der HTML-Element verrückt
if (weitermachen)
setTimeout("animFunk()",2000);
}
So sorgt die Funktion selbst dafür, dass sie in regelmäßigen Abständen aufgerufen (und das HTML-Elemente immer weiter gerückt) wird. Die if-Bedingung, die den Aufruf setTimeout() kontrolliert, wird benötigt, um die Animation irgendwann abzubrechen.
Die Animation, die wir in diesem Abschnitt erstellen werden, zeigt eine Studie zum Fressverhalten des Weißen Hais und sollte im Internet Explorer 4/5, Netscape Navigator 4 und Netscape 6-Browser laufen.
Abbildung 16.10: Drei Auschnitte aus der Animation
Schauen wir uns zuerst den reinen HTML-Code an:
Listing 16.2: HaiAnimation.html
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Der weiße Hai</title>
<style type="text/css">
body { background-color: #cdcdcd }
#hai { position: absolute; top: 100px; left: 20px; z-index: 2 }
#opfer { position: absolute; top: 100px; left: 520px; z-index: 1 }
</style>
<script language="JavaScript">
// hier fehlt noch der Skriptcode
</script>
</head>
<body onload="animate()">
<h1>Eine kleine Animation</h1>
<div id="hai"><img src="Hai.gif" width="332" height="140" /></div>
<div id="opfer"><img src="taucher.gif" width="90" height="80" /></div>
</body>
</html>
In den letzten Zeilen fällt auf, dass die Bilder in <div>-Tags eingeschlossen wurden. Dies ist erforderlich, da der Netscape Navigator keine direkte Verschiebung von <img>- Elementen erlaubt.
Des Weiteren fällt auf, dass den <div>-Tags IDs zugewiesen wurden. Wir benötigen diese nicht nur zur Verknüpfung mit den Stylesheets aus dem Header-Bereich der Webseite, sondern auch später, um im JavaScript-Code auf den Hai und den Taucher zugreifen zu können.
Damit wären wir bei den Stylesheets. Wie Sie sehen, dienen diese dazu, die Bilder an ihre Anfangspositionen zu rücken. Die absolute Positionierung hat aber auch noch einen weiteren Effekt: Netscape Navigator speichert alle absolut positionierten Elemente in seinem layers[]-Array. Das layers[]-Array wurde zwar nie in den HTML-Standard aufgenommen und wird auch vom Netscape 6-Browser nicht mehr unterstützt, doch stellt es die einzige Möglichkeit dar, Animationen zu schreiben, die im Navigator laufen.
Beachten Sie auch die z-index-Werte, die dafür sorgen, dass der Hai über dem Taucher angezeigt wird, wenn sich beide Bilder überlagern. So können wir den Eindruck erwecken, dass der Hai den Taucher verschluckt.
Lassen Sie uns jetzt den Skript-Code durchgehen. Beim Laden der Webseite werden die Anweisungen im Skript-Tag ausgeführt.
<script language="JavaScript">
var isNav4 = false;
var isNet6 = false;
var isIE = false;
var loop = 1;
var haibilder = new Array();
haibilder[0] = new Image();
haibilder[0].src = "hai.gif";
haibilder[1] = new Image();
haibilder[1].src = "hai2.gif";
Wir haben Boolesche Variablen zur Unterscheidung der Browser definiert und auf false gesetzt. Die globale Variable loop soll die Anzahl der Iterationen zählen und die Animation nach 50 Iterationen abbrechen.
Schließlich laden wir die beiden Haidarstellungen (mit geschlossenem und offenem Maul in ein JavaScript-Array.
Wenn der Besucher der Website auf den Start-Schalter drückt, wird die JavaScript- Funktion animate() aufgerufen (siehe HTML-Code oben). Diese ruft ihrerseits als Erstes die Funktion init() auf, die feststellt, in welchem Browser die Webseite angezeigt wird und dementsprechend eine der oben definierten Booleschen Variablen auf true setzt.
function init()
{
var brw = navigator.appName.toLowerCase();
if (brw.indexOf("microsoft") != -1) // Internet Explorer
{
isIE = true;
}
else if (brw.indexOf("netscape") != -1) // Netscape
{
if (parseInt(navigator.appVersion) < 5) // Navigator 4
{ // oder früher
isNav4 = true;
}
else // Netscape 6
{ // oder später
isNet6 = true;
}
}
else
{
alert("Unbekannter Browser, Animation wird vermutlich nicht funktionieren");
}
}
Damit wären wir bei der eigentlichen Animationsfunktion angelangt. Nach dem Aufruf von init() bewegt diese Hai und Taucher um einen Schritt weiter.
function animate()
{
init();
if(isIE)
{
document.all.hai.style.left = 20 * loop + "px";
document.all.opfer.style.top = 100 + 2*loop + "px";
document.all.opfer.style.left = 520 + 2*loop + "px";
}
else if (isNav4)
{
document.layers["hai"].left = 20 * loop;
document.layers["opfer"].top = 100 + 2*loop;
document.layers["opfer"].left = 520 + 2*loop;
}
else
{
var vhai = document.getElementById('hai');
vhai.style.left = 20 * loop + "px";
var vopfer = document.getElementById('opfer');
vopfer.style.top = 100 + 2 * loop + "px";
vopfer.style.left = 520 + 2 * loop + "px";
}
Die neuen Positionen werden als absolute Positionen berechnet. Der Einbau der Schleifenvariablen loop sorgt dafür, dass die Positionen von Iteration zu Iteration weiter vorgerückt werden. Für alle drei Browser erfolgt die Positionierung über die Eigenschaften top und left, die Browser unterscheiden sich allerdings darin, wie man auf diese Positionen zugreifen kann.
Im Internet Explorer nutzen wir die Tatsache, dass alle HTML-Elemente unter der proprietären document-Eigenschaft all verfügbar sind und über ihre ID - sofern sie über eine solche verfügen - angesprochen werden können. Die Eigenschaften top und left sind im Internet Explorer die CSS-Stylesheet-Eigenschaften und werden daher über das style-Unterobjekt angesprochen.
document.all.hai.style.left = 20 * loop + "px";
Im Netscape Navigator werden die absolut positionierten Elemente in das proprietäre layers-Array eingetragen und können mit ihrer ID als Index angesprochen werden. Der Navigator unterstützt keine CSS-Stileigenschaften, verfügt aber ebenfalls über Eigenschaften top und left, die man zur Positionierung verwenden kann (man hängt dann aber keine Einheit an den Zahlenwert an!).
document.layers["hai"].left = 20 * loop;
Der Netscape 6-Browser unterstützt wie der Internet Explorer die CSS-Stileigenschaften und das style-Unterobjekt. Allerdings muss man sich für den Zugriff auf die HTML- Elemente der DOM-Methoden, hier getElementById() bedienen.
var vhai = document.getElementById('hai');
vhai.style.left = 20 * loop + "px";
Jetzt sind beide Bilder vorgerückt. Als Vorbereitung auf die nächste Iteration inkrementieren wir den internen Zähler loop:
++loop;
Um die Animation ein wenig interessanter zu machen, tauschen wir im Internet Explorer und im Netscape 6-Browser nach 10 Iterationen das Hai-Bild (der Hai reißt dann das Maul auf).
if((loop > 10 && loop < 15) && (isIE || isNet6) )
{
document.images[0].src = haibilder[1].src;
}
Nach 15 Iterationen ist der Hai so weit vorgerückt, dass er den Taucher halb verdeckt. Damit der Taucher später nicht wieder hinter dem Hai auftaucht, verbergen wir nach 15 Iterationen das Taucher-Bild, indem wir die visibility-Eigenschaft auf hidden (verborgen) setzen. Wie zuvor bei der Positionierung müssen wir dabei für die verschiedenen Browser unterschiedliche Wege gehen.
Im Internet Explorer und im Netscape 6-Browser schließen wir danach auch noch das Maul des Hais.
if(loop > 15)
{
if(isIE)
{
document.all.opfer.style.visibility = "hidden";
}
else if (isNav4)
{
document.layers["opfer"].visibility = "hidden";
}
else
{
var vopfer = document.getElementById('opfer');
vopfer.style.visibility = "hidden";
}
if (isIE || isNet6)
document.images[0].src = haibilder[0].src;
}
Damit wären wir am Ende der Funktion. Jetzt müssen wir nur noch dafür sorgen, dass die animate()-Funktion so lange weiter aufgerufen wird, bis ca. 50 Iterationen durchlaufen sind. Dafür würde im Grunde eine if-Bedingung genügen. Wir wollen den Hai aber in der mittleren Bewegungsphase, wenn er das Maul aufreißt, schneller schwimmen lassen. Daher rufen wir setTimeout() in Abhängigkeit von der Iteration (Wert in loop) mit verschiedenen Zeitangaben auf.
if(loop < 8)
setTimeout("animate()",200);
else if (loop < 18)
setTimeout("animate()",100);
else if (loop < 50)
setTimeout("animate()",200);
}
</script>
Damit hätten wir Ihnen nun gezeigt, wie man CSS-StyleSheets zur Animation nutzen kann. Die schwierigste und lästigste Arbeit ist dabei zweifelsohne die Unterstützung der verschiedenen Browser - und dabei kann man noch nicht einmal sicher sein, ob die Animation in den nächsten Browserversionen auch noch lauffähig ist. Es bleibt aber zu hoffen, dass sich die großen Browser mehr und mehr dem DOM-Standard annähern (Netscape hat dies in seinem Netscape 6-Browser ja schon getan) und wir uns die Fallunterscheidungen in baldiger Zukunft sparen können.
GIF-Animationen, sofern sie gut gemacht sind, laufen meist schneller und weniger ruckhaft als vergleichbare JavaScript-Animationen. Mit JavaScript kann man dafür
Ich hoffe, Sie haben es nicht versäumt, Kapitel 15 über die Erstellung von Java-Applets zu lesen. Denn ohne Grundwissen über den Aufbau von Applets, die Applet- Standardmethoden, die Auswertung von HTML-Parametern und die grundlegende Java- Syntax werden Sie in diesem Abschnitt nicht viel verstehen. Sie haben Kapitel 15 gelesen? Na prima, dann können wir uns gleich auf ein neues Konzept stürzen: die Threads.
Das englische Wort »Thread« bedeutet soviel wie »Faden«. Wenn man diesen Faden als einen Handlungsfaden auffasst, bekommt man schon eine ganz gute Ahnung davon, worum es bei der Thread-Programmierung geht. Normalerweise besteht ein Applet (wie im Übrigen jedes beliebige Programm) aus einem einzigen Handlungsfaden, der beim Programmstart aufgenommen und Anweisung für Anweisung verfolgt und ausgeführt wird.
Manchmal wäre es aber von Vorteil, wenn ein Programm zwei Aufgaben gleichzeitig erledigen könnte. Schauen wir uns ein Beispiel aus der täglichen Praxis an. Sie sitzen an Ihrem Computer und bearbeiten in Ihrem Textverarbeitungsprogramm ein größeres Dokument. Das Textverarbeitungsprogramm verfügt über einen einzelnen Handlungsfaden, der ausgeführt wird, während Sie mit dem Programm arbeiten. Jetzt wollen Sie das Dokument auf dem aktuellen Bearbeitungsstand ausdrucken. Das Textverarbeitungsprogramm muss das Dokument (falls es sehr umfangreich ist und der Drucker nur über wenig eigenen Speicher verfügt) häppchenweise aufbereiten und an den Drucker schicken. Wenn Ihr Textverarbeitungsprogramm nicht threadfähig ist, konzentriert es sich jetzt ganz auf die Bearbeitung der Druckausgabe und Sie haben keine Chance, den Text, während er gedruckt wird, weiter zu bearbeiten - älteren Windows- Anwender dürfte ein solches Szenario wohl bekannt sein. ;-) Ist das Programm dagegen threadfähig, erzeugt es für das Ausdrucken einen neuen Thread. Dieser neue Thread oder Handlungsfaden bearbeitet die Druckerausgabe. Der Hauptthread des Programms wird davon nicht beeinträchtigt und kann weiter ausgeführt werden, das heißt, Sie können während des Druckens mit dem Programm normal weiter arbeiten.
Multithreading ist nicht nur eine Frage der Implementierung eines Programms, sondern auch eine Frage des Betriebssystems. Dieses muss dafür ausgelegt sein, mehrere Programme oder Threads1 gleichzeitig ausführen zu können. Den Begriff »gleichzeitig« darf man dabei nicht zu wörtlich nehmen, besser wäre es von quasi gleichzeitig oder quasiparallel zu reden. |
Wenn ein Thread ausgeführt wird, belegt es den Prozessor des Rechners. Hier, im Prozessor, wird der Code des Threads abgearbeitet und ausgeführt. Hat ein Rechner nur einen einzigen Prozessor, kann aber auch immer nur ein Thread gleichzeitig ausgeführt werden. Wie ist dann aber die gleichzeitige Ausführung von mehreren Threads möglich? |
Wann immer ein Thread gestartet wird, nimmt das Betriebssystem den Thread in Empfang und reiht ihn in eine schön geordnete Warteschleife ein. Das Betriebssystem geht die Warteschleife in einem endlosen Zyklus durch, greift sich einen nach dem anderen die Threads heraus und stellt ihnen für eine bestimmte Zeit den Prozessor zur Verfügung. Während ein Thread über den Prozessor verfügt, wird sein Code ausgeführt. Nach kurzer Zeit klopft dann aber das Betriebssystem an, gibt Bescheid, dass die Zeit abgelaufen ist, und teilt dem nächsten Thread den Prozessor zu, während sich der alte Thread wieder in die Warteschleife einreiht. So werden die einzelnen Threads nacheinander immer Stück für Stück ausgeführt. Ist der Rechner schnell genug, läuft diese häppchenweise Ausführung der Threads aber so schnell ab, dass der Anwender gar nichts davon merkt, sondern das Gefühl hat, dass die einzelnen Threads (oder Programme) parallel ausgeführt werden. |
Diese quasiparallele Ausführung ist eine Eigenschaft des Betriebssystems. Multithreadfähige Betriebssysteme sind Unix/Linux sowie Windows 95/98/NT/2000, aber nicht Windows 3.x. Die Aufspaltung eines Programms in mehrere Threads ist dagegen eine Frage der Implementierung des Programms. |
1 |
Wenn wir Animationen in Java-Applets implementieren, nutzen wir die Möglichkeiten der Thread-Programmierung. Zum einem können die Animationen dann parallel zum Hauptthread des Applets ausgeführt werden, zum anderen können wir mit Hilfe der für Threads verfügbaren Methoden die Animationen gezielt starten, zeitweise anhalten oder ganz stoppen.
In Java gibt es zwei Möglichkeiten, Threads zu implementieren:
Die Realisierung eines Threads ist zunächst ganz einfach. Man leitet eine eigene Klasse von Thread ab
class MeineKlasse extends Thread
{
und erbt dadurch eine Reihe von interessanten Methode, die zur Steuerung eines Threads benötigt werden (siehe Tabelle 16.1).
Will man Applets threadfähig machen, stößt man auf das Problem, dass man die Appletklasse nicht von der Klasse Thread ableiten kann, weil sie ja bereits von der Basisklasse Applet abgleitet wird (und Java keine Ableitung von zwei Basisklassen erlaubt). Dass man Applets dennoch threadfähig machen kann, verdanken wir der Schnittstelle Runnable.
Eine Schnittstelle kann man sich vielleicht am einfachsten als eine Klasse vorstellen, in der eine oder mehrere Methoden deklariert, aber nicht definiert sind. Das heißt, die Schnittstelle gibt an, wie die Methoden heißen und welche Parameter sie übernehmen, aber sie definiert keine Anweisungsblöcke für die Methoden. Schnittstellen sind für Java-Klassen so etwas wie Zertifikate. Wenn Sie sich irgendwo als Webdesigner oder Programmierer bewerben wollen, müssen Sie nachweisen, dass Sie über Erfahrungen in Webdesign, JavaScript oder einer Programmiersprache wie Java verfügen. Dazu belegen Sie einen Kursus oder ein Studium, das Sie mit einem Zertifikat abschließen. Wenn eine Java-Klasse am Thread-Mechanismus teilhaben will, leitet sie sich von der Klasse Thread ab oder implementiert die Schnittstelle Runnable und weist sich dadurch als threadfähig aus.
Eine Klasse kann sich von beliebig vielen Schnittstellen ableiten. Man spricht dann allerdings nicht von Ableitung, sondern von Implementierung, denn eine Klasse, die eine Schnittstelle benutzt, muss alle in der Schnittstelle deklarierten Methoden implementieren (das heißt, sie muss Anweisungsblöcke für die Methoden definieren). Im Falle der Schnittstelle Runnable ist dies nur eine Methode: run().
Was also ist zu tun, wenn man ein Applet threadfähig machen will?
public class MeinApplet extends Applet implements Runnable
{
public void run()
{
// Anweisungen
}
public class Laufschrift extends Applet implements Runnable
{
Thread m_thread = null;
...
public void start()
{
if (m_thread == null)
{
m_thread = new Thread(this);
...
public void start()
{
if (m_thread == null)
{
m_thread = new Thread(this);
m_thread.start();
}
}
Wie dies in der Praxis aussieht, demonstriert der folgende Abschnitt.
Das folgende Applet erzeugt eine Laufschrift, die endlos von rechts nach links über das Anzeigefeld des Applets läuft. Über spezielle Parameter kann man vom HTML-Code aus den Text, die Farben und die Schriftgröße der Laufschrift einstellen.
Listing 16.3: Laufschrift.java
// Laufschrift-Applet
import java.awt.*;
import java.applet.*;
public class Laufschrift extends Applet implements Runnable
{
Thread m_thread = null;
String m_text;
int m_breite;
int m_hoehe;
int m_hg_rot, m_hg_gruen, m_hg_blau;
int m_vg_rot, m_vg_gruen, m_vg_blau;
int m_font_groesse;
int x, y;
public void init()
{
m_text = getParameter("text");
m_breite = Integer.valueOf(getParameter("breite")).intValue();
m_hoehe = Integer.valueOf(getParameter("hoehe")).intValue();
m_hg_rot = Integer.valueOf(getParameter("hg_rot")).intValue();
m_hg_gruen = Integer.valueOf(getParameter("hg_gruen")).intValue();
m_hg_blau = Integer.valueOf(getParameter("hg_blau")).intValue();
m_vg_rot = Integer.valueOf(getParameter("vg_rot")).intValue();
m_vg_gruen = Integer.valueOf(getParameter("vg_gruen")).intValue();
m_vg_blau = Integer.valueOf(getParameter("vg_blau")).intValue();
m_font_groesse =
Integer.valueOf(getParameter("font_size")).intValue();
x = m_breite;
y = m_hoehe/2;
setBackground(new Color(m_hg_rot, m_hg_gruen, m_hg_blau));
setForeground(new Color(m_vg_rot, m_vg_gruen, m_vg_blau));
setFont(new Font("Monospaced", Font.BOLD, m_font_groesse));
}
public void start()
{
if (m_thread == null)
{
m_thread = new Thread(this);
m_thread.start();
}
}
public void stop()
{
if (m_thread != null)
{
m_thread.interrupt();
m_thread = null;
}
}
public void run()
{
while (m_thread == Thread.currentThread())
{
try
{
repaint();
Thread.sleep(100);
}
catch (InterruptedException e)
{
return;
}
}
}
public void paint(Graphics gc)
{
FontMetrics fm = gc.getFontMetrics();
gc.drawString( m_text, x, y );
x -= 5;
if( x < -fm.stringWidth( m_text ) )
x = m_breite;
}
}
Lassen Sie uns gemeinsam den Lebenslauf dieses Applets verfolgen.
Wenn eine Webseite mit diesem Applet in einen Browser geladen wird, richtet das Applet zuerst einmal Speicher für eine Reihe von Instanzvariablen ein: eine Instanzvariable m_thread für den Thread, eine Reihe von Instanzvariablen für die Argumente, die vom HTML-Code übergeben werden und zwei Instanzvariablen x und y, die angeben, wo die Laufschrift in jedem Schritt einzuzeichnen ist.
Thread m_thread = null;
String m_text;
int m_breite;
int m_hoehe;
int m_hg_rot, m_hg_gruen, m_hg_blau;
int m_vg_rot, m_vg_gruen, m_vg_blau;
int m_font_groesse;
int x, y;
Dann ruft der Browser die Applet-Methode init() auf.
public void init()
{
m_text = getParameter("text");
m_breite = Integer.valueOf(getParameter("breite")).intValue();
m_hoehe = Integer.valueOf(getParameter("hoehe")).intValue();
m_hg_rot = Integer.valueOf(getParameter("hg_rot")).intValue();
m_hg_gruen = Integer.valueOf(getParameter("hg_gruen")).intValue();
m_hg_blau = Integer.valueOf(getParameter("hg_blau")).intValue();
m_vg_rot = Integer.valueOf(getParameter("vg_rot")).intValue();
m_vg_gruen = Integer.valueOf(getParameter("vg_gruen")).intValue();
m_vg_blau = Integer.valueOf(getParameter("vg_blau")).intValue();
m_font_groesse =
Integer.valueOf(getParameter("font_size")).intValue();
x = m_breite;
y = m_hoehe/2;
setBackground(new Color(m_hg_rot, m_hg_gruen, m_hg_blau));
setForeground(new Color(m_vg_rot, m_vg_gruen, m_vg_blau));
setFont(new Font("Monospaced", Font.BOLD, m_font_groesse));
}
In dieser Methode liest das Applet die HTML-Argumente ein. Ein passender HTML-Code zur Einbindung des Applets würde beispielsweise wie folgt aussehen:
Listing 16.4: Auszug aus Laufschrift.html
<applet code="Laufschrift.class" width="600" height="40">
<param name="text" value="Heute Zucchinis im Sonderangebot" />
<param name="breite" value="600" />
<param name="hoehe" value="40" />
<param name="hg_rot" value="255" />
<param name="hg_gruen" value="0" />
<param name="hg_blau" value="0" />
<param name="vg_rot" value="255" />
<param name="vg_gruen" value="255" />
<param name="vg_blau" value="255" />
<param name="font_size" value="18" />
</applet>
Der Text für die Laufschrift wird in der Instanzvariablen m_text gespeichert.
Die aktuellen Anzeigepositionen für die Laufschrift, x und y, werden so gesetzt, dass die Laufschrift am rechten Rand in mittlerer Höhe des Laufbandes (der Anzeigefläche des Applets) beginnt.
Das Setzen der Hintergrund- und Vordergrundfarbe ist etwas umständlich, da es kein einfaches Verfahren zur Umwandlung von Strings mit hexadezimalen Werten (beispielsweise »0xFF0000«, wie Sie getParameter() zurückliefern würde) in hexadezimale Integer-Werte (wie sie der Konstruktor der Klasse Color erwartet) gibt. Aus diesem Grunde übergeben wir für jeden Farbanteil der RGB-Farben einen eigenen Integer-Wert im Bereich zwischen 0 und 255.
Schließlich wird noch eine neue proportionale, fette Schrift in der angegebenen Größe erzeugt und als Standardschrift für die Applet-Ausgabe eingerichtet (Aufruf von setFont()).
Nach der init()-Methode ruft der Browser die start()-Methode auf.
public void start()
{
if (m_thread == null)
{
m_thread = new Thread(this);
m_thread.start();
}
}
In der start()-Methode prüfen wir, ob bereits ein Thread-Objekt existiert. Wenn dies nicht der Fall ist, liefert die if-Bedingung true zurück und wir erzeugen ein neues Thread- Objekt und starten den Thread durch Aufruf seiner start()-Methode. Wie Sie aus der Einleitung zu diesem Abschnitt wissen, wird daraufhin automatisch die run()-Methode des Threads aufgerufen. Da wir dem Thread-Konstruktor das Schlüsselwort this übergeben haben, das unser Applet repräsentiert, ist dies die run()-Methode aus unserem Applet.
public void run()
{
while (m_thread == Thread.currentThread())
{
try
{
repaint();
Thread.sleep(100);
}
catch (InterruptedException e)
{
return;
}
}
}
Die run()-Methode besteht im Wesentlichen aus einer while-Schleife, die so lange ausgeführt wird, wie das Applet angezeigt wird. In der Schleife wird das nächste Bild der Animation gezeichnet (Aufruf von repaint()). Danach wird der Thread für 100 Millisekunden schlafen gelegt (Aufruf von Thread.sleep(100);) - ansonsten würde die Schrift so schnell animiert, dass man sie nicht lesen könnte.
Kompliziert wird die Sache durch zwei Umstände:
Die run()-Methode ruft alle Zehntelsekunde die Methode repaint() auf, die ihrerseits die paint()-Methode des Applets aufruft.
public void paint(Graphics gc)
{
FontMetrics fm = gc.getFontMetrics();
gc.drawString( m_text, x, y );
x -= 5;
if( x < -fm.stringWidth( m_text ) )
x = m_breite;
}
Die paint()-Methode lässt sich zuerst ein FontMetrics-Objekt zurückliefern, über das Sie Informationen zu der verwendeten Schrift abfragen kann. Dann zeichnet Sie den Schriftzug (Inhalt von m_text) an den Koordinaten x, y.
Damit die Schrift beim nächsten Mal weiter rechts eingezeichnet wird, wird der Wert von x anschließend um 5 verringert.
Jetzt müssen wir nur noch dafür sorgen, dass die Animation wieder von vorne beginnt, wenn die Schrift am rechten Rand entschwunden ist. Dazu lassen wir uns von der FontMetrics-Methode stringWidth() die Breite des Textes in m_text zurückliefern. Wenn x kleiner ist als die negative Breite des Textes, ist der Text ganz am linken Rand verschwunden. Dann setzen wir x zurück auf die Breite des Applet-Anzeigefeldes.
Irgendwann verlässt der Besucher die Webseite. Dann ruft der Browser die stop()- Methode des Applets auf.
public void stop()
{
if (m_thread != null)
{
m_thread.interrupt();
m_thread = null;
}
}
In der stop()-Methode prüfen wir, ob der Thread noch ausgeführt wird. Wenn ja (if- Bedingung liefert true), wird der Thread abgebrochen (Aufruf von interrupt()) und unsere Thread-Variable m_thread setzen wir auf null. So erreichen wir, dass die run()- Methode sofort beendet wird, und die start()-Methode kann anhand des Wertes von m_thread feststellen, ob sie einen neuen Thread erstellen soll oder nicht (siehe oben).
Abbildung 16.11: Java-Laufschrift
Macromedia Flash ist eines der populärsten Grafikprogramme zur Erstellung interaktiver Grafiken und Animationen für das Web (obwohl es nicht unter Unix/Linux läuft). Es wäre hoffnungslos, wollten wir im Rahmen dieses Buches versuchen, Ihnen Flash mit all seinen Möglichkeiten und Konzepten in nur halbwegs angemessener Ausführlichkeit vorzustellen. Wir werden uns daher auf das Thema beschränken, das uns im Rahmen dieses Abschnitts am meisten interessieren: die Erstellung von Animationen mit Flash. Wir werden zwar auch dieses Thema nicht vollständig behandeln können, aber wir können Sie in die grundlegenden Techniken einführen, mit Ihnen zusammen erste Animationen erstellen, schauen wie man mit Hilfe von Flash die Erstellung von Animationen automatisieren kann und zum Abschluss eine schon recht komplexe Animation implementieren. Danach sollten Sie in der Lage sein, mit Flash eigene einfache Animationen aufzusetzen oder sich mit Hilfe weiterführender Literatur tiefer in Flash einzuarbeiten.
Eine aktuelle Trial-Version kann man sich von http://www.macromedia.com herunterladen.
Als erste Animation wollen wir ein Standardbeispiel für Animationstechnik nachstellen: den hüpfenden Ball.
Abbildung 16.12: Hüpfender Ball
Wenn Sie selbst ein neues Dokument (sprich eine neue Animation) beginnen wollen, rufen Sie den Befehl File/New auf.
Das Dokumentenfenster Ball1.fla ist in zwei Bereiche geteilt:
Beide Bereiche kann man über die entsprechenden Befehle im Menü View ein- und ausblenden.
Umriss- und Füllfarbe können Sie in der Tools-Leiste im Bereich Colors festlegen.
In der Zeitleiste wird jetzt im ersten Frame ein Kreis angezeigt. Dies ist nicht unser Ball, sondern ein Symbol, das anzeigt, das der Frame ein nicht mehr leerer Schlüsselframe ist (mehr dazu weiter unten).
Klicken Sie dazu mit der rechten Maustaste in den nächsten Frame in der Zeitleiste und wählen Sie den Befehl Insert Keyframe aus.
Um besser kontrollieren zu können, wie sich die Animation von Frame zu Frame verändert, bietet Flash Ihnen die Möglichkeit, die benachbarten Frames in aufgehellten Farben mit einzublenden. Sie müssen dazu nur unten in der Zeitleiste den Schalter Onion Skin (Zwiebelhaut) drücken und in der über den Frames gelegenen Skala einstellen, wie viele Frames die Zwiebelhautdarstellung umfassen soll (siehe Abbildung 16.15).
Abbildung 16.15: Zwiebeldarstellung der Animation
Zum Testen der Animation gibt es verschiedene Möglichkeiten:
Vielleicht läuft Ihnen die Animation zu schnell ab. Dann rufen Sie noch einmal den Befehl Modify Movie auf und ändern Sie die Frame-Rate (Anzahl der Bilder pro Sekunde).
Abbildung 16.16: Animationseigenschaften setzen
Flash-Animationen werden mit Hilfe des <object>- beziehungsweise des <embed>-Tags in Webseiten eingebettet. Sie brauchen den betreffenden Code nicht selbst aufzusetzen, lassen Sie ihn lieber direkt von Flash generieren.
Achten Sie darauf, dass auf der Registerkarte Formats die Option HTML gesetzt ist. Wechseln Sie dann zur Registerkarte HTML und legen Sie dort fest, wie die Flash- Animation in die Webseite eingebettet werden soll - üblicherweise brauchen Sie nur die Optionen unter Playback zu bearbeiten (siehe Abbildung 16.17).
Danach finden Sie in dem Verzeichnis, in dem Sie die Flash-Animation (.fla) abgespeichert haben,
Voraussetzung ist allerdings, dass die Browser das Flash-Abspielplugin (den frei verfügbaren Flash-Player) installiert haben (das mittlerweile aber standardmäßig in den großen Browsern integriert ist).
Listing 16.5: Von Flash erzeugte HTML-Datei: ball1.html
<HTML>
<HEAD>
<TITLE>Ball1</TITLE>
</HEAD>
<BODY bgcolor="#FFFFFF">
<!-- URL's used in the movie-->
<!-- text used in the movie-->
<OBJECT classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
codebase="http://download.macromedia.com/pub/shockwave/cabs
¬/flash/swflash.cab#version=5,0,0,0"
WIDTH=150 HEIGHT=300>
<PARAM NAME=movie VALUE="Ball1.swf">
<PARAM NAME=menu VALUE=false>
<PARAM NAME=quality VALUE=high>
<PARAM NAME=bgcolor VALUE=#FFFFFF>
<EMBED src="Ball1.swf" menu=false quality=high bgcolor=#FFFFFF
WIDTH=150 HEIGHT=300 TYPE="application/x-shockwave-flash"
PLUGINSPAGE="http://www.macromedia.com/shockwave/download/
¬index.cgi?P1_Prod_Version=ShockwaveFlash">
</EMBED>
</OBJECT>
</BODY>
</HTML>
Das <object>-Tag enthält den Code für die Einbettung in den Internet Explorer (wobei der Flash-Player über eine eindeutige Objekt-ID spezifiziert wird). Das <embed>-Tag bindet die Animation so ein, dass sie vom Netscape Navigator und vom Netscape 6-Browser identifiziert und abgespielt werden kann. Durch die Einbettung des <embed>-Tags in das <object>-Tag wird sichergestellt, dass alle drei Browser den für sie relevanten Code finden und nur diesen ausführen.
Sie können die von Flash erzeugte Webseite weiter bearbeiten oder den Code für die Einbettung der Animation in eine andere Webseite kopieren.
Man kann sich die Erstellung von Animationen in Flash wesentlich erleichtern, indem man nur die Schlüsselframes einer Animation vorgibt und die dazwischenliegenden Frames automatisch von Flash generieren lässt. Was aber sind in diesem Sinne Schlüsselframes?
Ein Schlüsselframe ist in diesem Sinne jeder Frame, in dem die Animation (sprich die Bewegung des animierten Objekts) eine andere Richtung nimmt. Im Falle unseres hüpfenden Balls sind die Schlüsselframes schnell identifiziert: es sind
Im Folgenden werden Sie sehen, wie man die »Hüpfender Ball«-Animation durch Definition der drei Schlüsselframes und einer Technik namens Motion-Tweening erzeugt.
Der erste Frame wird - zusammen mit dem neuen Dokument - von Flash angelegt und ist automatisch ein Schlüsselframe.
Markieren Sie dazu den gezeichneten Ball im Arbeitsbereich und rufen Sie den Menübefehl Insert/Create Motion Tween auf.
Die für eine Animation eingerichteten Symbole können Sie sich über den Befehl Window/Library anzeigen lassen.
Ziehen Sie dann den Ball im fünften Frame nach unten, und Flash erzeugt in den zwischen den Schlüsselframes gelegenen Frames die Zwischenbilder der Animation.
In der Zeitleiste wird der Motion Tween-Bereich durch blaue Frames und einen durchgezogenen Pfeil vom Anfangs-Schlüsselframe zum End-Schlüsselframe angezeigt (siehe Abbildung 16.19).
Flash kann neben Bewegungen auch Formen animieren (Morphing). In diesem Falle gehen Sie grundsätzlich genauso vor, wie beim Motion Tween. Statt aber im End- Schlüsselframe das zu animierende Objekt zu verschieben, verändern Sie seine Form (oder zeichnen eine neue Form). Außerdem müssen Sie den Befehl Window/Panels/ Fame aufrufen und in dem erscheinenden Dialogfeld unter Tweening die Option Shape auswählen.
Zum Schluss wollen wir noch eine etwas komplexere Animation erstellen. Sie soll einen von einer Fliege umschwirrten Cartoon-Kopf vor einem Sonnenuntergang zeigen. Sonnenuntergang, Kopf und Fliege werden wir jeweils auf eigenen Ebenen anlegen - so bleibt die Animation übersichtlich und wir können die Ebenen für sich bearbeiten. Für die Animation der Fliege werden wir eine weitere Variante des Motion Tweens kennen lernen: die Bewegung entlang eines Laufpfades.
Als Hintergrund unserer Animation wollen wir das Photo eines Sonnenuntergangs verwenden. Die Bilddatei, himmel.jpg, finden Sie auf der Buch-CD.
Das Hintergrundbild soll die gesamte Animation über unverändert bleiben. Sagen wir unsere Animation soll 15 Frames umfassen. Wir könnten jetzt 14 weitere Frames anlegen und das Hintergrundbild in jeden dieser Frames neu importieren. Wir können uns die Arbeit aber auch vereinfachen.
In der Zeitleiste erscheinen die Frames jetzt grau, was bedeutet, dass sie alle den gleichen Inhalt haben wie der vorangehende Schlüsselframe (mit dem Punkt). Der letzte Frame der Reihe enthält ein weißes Kästchen.
Über diesen Hintergrund wollen wir den Cartoon-Kopf aus kopf.gif legen. Dazu verwenden wir eine zweite Ebene.
Die neue Ebene wird in der Zeitleiste über der alten Ebene eingeblendet.
Da wir an der alten Ebene nichts mehr verändern wollen, ist es sinnvoll, die alte Ebene vor unabsichtlichen Änderungen zu schützen. Klicken Sie in der Layer 1 auf den Punkt unter dem Sicherheitsschloss.
Verschieben Sie den Kopf irgendwo an den unteren Rand der Leinwand.
Da wir auch an dieser Ebene nichts mehr verändern wollen, ist es sinnvoll, die Ebene vor unabsichtlichen Änderungen zu schützen. Klicken Sie in der Layer 2 auf den Punkt unter dem Sicherheitsschloss.
Beachten Sie, dass Flash den importierten Kopf automatisch in alle Frames der Animation kopiert. Beachten Sie des Weiteren, dass der Hintergrund nur durchscheint, wenn das GIF-Bild des Kopfes mit transparenter Hintergrundfarbe abgespeichert ist.
Die schwarze Fliege sieht man nur schlecht vor dem Hintergrund des Sonnenuntergangs. Da der Hintergrund für die weitere Bearbeitung der Animation nicht wichtig ist, blenden wir ihn aus.
Als Erstes machen wir aus der statischen Animation der Fliege einen Motion Tween.
Die Fliege soll aber nicht auf einer geraden Linie zwischen Start- und Endpunkt verschoben werden, sondern auf einer Wellenlinie. Diese Wellenlinie, den Laufpfad des Motion Tweens, müssen wir als eigene Ebene einrichten.
Aktivieren Sie zuvor die Zwiebelhüllenansicht und dehnen sie diese soweit aus, dass sowohl Start- wie Endpunkt der Fliege eingeschlossen sind (siehe oben) Dies ist zwar nicht unbedingt notwenig, aber es erleichtert das Einzeichnen des Laufpfades, wenn Start- und Endpunkt zu sehen sind.
Wählen Sie dann in der Tools-Leiste das Stift-Werkzeug (Pencil) und zeichnen Sie den Laufpfad ein.
Start- und Enddarstellung des zu bewegenden Objekts müssen direkt über Beginn und Ende des Laufpfads liegen. Wechseln Sie gegebenenfalls in die Ebene der Fliege und positionieren Sie in Start- und Ende-Frame das Kreuz des Fliegen-Objekts über dem Laufpfad.
Jetzt wollen wir nur noch erreichen, dass unsere Fliege sich so dreht, wie sie fliegt.
Abbildung 16.23: Objekte in Pfadrichtung drehen
Damit beenden wir unsere Einführung in die Erstellung von Flash-Animationen. Viele interessante Optionen und Möglichkeiten der Flash-Software konnten wir nicht ansprechen, beispielsweise das Abbremsen von Bewegungen oder das Einbinden von Sound. Wenn Sie mehr über Flash erfahren wollen, schauen Sie sich die Dokumentation an, die der Software beiliegt oder suchen Sie nach geeigneter Fachliteratur.
Nach dem anstrengenden Java-Kapitel am gestrigen Tag haben wir uns heute ein wenig Entspannung gegönnt und ein Thema angeschnitten, für das sich wohl jeder Webdesigner begeistern kann: der Erstellung von Animationen.
Nach einer ganz kurzen Einführung in einige Grundbegriffe der Animationstechnik sind wir direkt in media res gegangen und haben uns angeschaut, wie man mit Hilfe von
Animationen für Webseiten erstellen kann.
Wir haben Ihnen Beispiele für Bildwechsler, Zeichentrickanimationen und Laufschriften gezeigt und Sie in die Arbeit mit dem Ulead GIF-Animator sowie der Flash-Software von Macromedia eingeführt.
Frage:
Kann man mit Java auch Animationen mit Bildern schreiben?
Antwort:
Ja, allerdings muss man dazu wissen, wie man Bilder in Applets lädt, was nicht
ganz trivial ist (siehe entsprechende Fachliteratur).
Frage:
Ist Flash auch für den Macintosh verfügbar?
Antwort:
Ja, nur für UNIX/Linux-Plattformen gibt es derzeit noch keine Flash-Software.
Der Workshop enthält Quizfragen, die Ihnen helfen sollen, Ihr Wissen zu festigen, und Übungen, die Sie anregen sollen, das eben Gelernte umzusetzen und eigene Erfahrungen zu sammeln. Versuchen Sie, das Quiz und die Übungen zu beantworten und zu verstehen, bevor Sie zur Lektion des nächsten Tages übergehen.
Zu dem heutigen Tag gibt es keine vorgeschriebenen Übungen. Nutzen Sie die Zeit, um mit Hilfe irgendeiner der an diesem Tag beschriebenen Techniken eine eigene Animation zu implementieren.