Web Animation

Siehe auch Webanimation bei Media Event

siehe auch Selfhtml Wiki

Die Web Animation API ist ein leistungsfähges Script, um CSS Eigenschaften zu animieren. Es wird von allen modernen Browsern unterstützt. Es gibt gewisse Übereinstimmungen zu CSS Animationen. Deswegen ist es sehr hilfreich, wenn man sich vorerst damit vertraut macht.

Der Aufruf von animate () benötigt 2 Argumente:

  1. Ein ein Array von Keyframes mit den CSS-Eigenschaften, die animiert werden sollen. Siehe dazu auch die keyframe Regel in CSS.
  2. Ein Objekt mit Dauer und der Zahl der Wiederholungen. Siehe dazu die entsprechenden Eigenschaften in CSS. Beachte, dass einige Werte anders lauten. Später mehr dazu.

 animate (keyframes, options).

Beispiel 1

let myAni = document.getElementById("moonface").animate (
	[
		{ transform: "rotate(0deg)" },
		{ transform: "rotate(360deg)" }
	],
	{
		duration: 3000,
		iterations: Infinity
	}
);

Keyframes und Timline

Beide Argumente kann man in Konstanten oder Variablen ablegen und der animate() Funktion zuweisen. Die beiden Konstanten werden im nächsten Abschnitt genauer erläutert.

var myAni = document.getElementById("bild").animate(bildKeyframe, bildTiming);

Array von Keyframes

Array von Keyframes, welches die CSS Eigenschaften und Werte nacheinander aufführt die animiert werden sollen. Die Zeitwerte (Prozent) der CSS Keyframes brauchen nicht gesetzt werden. Die Eigenschaften werden gleichmäßig über die Dauer der Animation verteilt. Man kann jedoch einen offset Wert von 0 bis 1 mit Komma getrennt angeben.

Im Beispiel wird die erste Eigenschaft auf 50% der Dauer gesetzt, so als hätte man in CSS am Anfang 50%{opacity:1} angegeben.

        const bildKeyframe = [
                { opacity: 1, width: "50vw", offset: 0.5 },
                { opacity: 0, width: "100vw" },
            ];

Das Beispiel entspricht folgender CSS Keyframe Regel.

            @keyframes myAni {
                50% {
                    opacity: 1;
                    width: 50vw;
                }

                100% {
                    opacity: 0;
                    width: 100vw;
                }

Objekt mit Timline Eigenschaften

  const bildTiming = {
                duration: 6000,
                iterations: 1,
                fill: "forwards"
            };

Weitere Eigenschaften könnten angefügt werden, die duration darf nicht fehlen. Diese Timline Eigenschaften werden in CSS dem Selektor zugewiesen. Sie entsprechen den CSS Eigenschaften animation-duration, animation-iteration-count, animation-fill-mode.

Das Beispiel enspricht folgender CSS Syntax für ein HTML Element mit der id="bild" und einer Keyframeregel namens myAni.

#bild {
    animation-name: myAni;
    animation-duration: 6s;
    animation-iteration-count: 1;
    animation-fill-mode: "forwards;"
}

Wie man sieht ist die Schreibweise der Eigenschaften anders und auch die Werte unterscheiden sich.

CSS Javascript Wert Info
animation-duration duration 500 Wert in Millisekunden
anination-iteration-count iterations 3
Infinity
Zahlenwert oder Infinity
animation-fill-mode fill none
forwards
backwards
both
Bestimmt ob die CSS Eigenschaft vor und/oder nach der Animation beibehalten wird.
animation-delay delay 500 Wert in Millisekunden
  endDelay 500 Wert in Millisekunden , Verzögerung am Ende der gesmaten Animtion, aber nicht zwischen mehrmaligen Durchläufen. Die Zeit (currentTime) läuft weiter bis nach dem endDelay
animation-direction direction normal
reverse
alternate
alternate-reverse
Die Richtung der Animation vorwärts rückwärts oder hin und her bei mehrmaligen Durchläufen.
animation-timing-function easing linear
ease
ease-in
ease-out
ease-in-out
cubic-bezier(0.24,4,0)
steps(integer)
Beschleunigung, der Standardwert ist in Javascript linear.
steps() lässt die Animtion springen, wie beim Sekundenzeiger
endDelay  
iterationStart  
composite
iterationsComposite
animation-name Anstatt eines Namens der Keyframeregel vergibt man einen Variablennamen, welcher den Aufruf der Animation enthält.
var myAni = document.getElementById("bild").animate(bildKeyframe, bildTiming);
animation-play-state Abspielen und Stoppen kann man mittels Methoden pause() und play() steuern.
myAni.pause()
myAni.play()

Desweiteren kann man man mit myAni.playState abfragen ob die Animtion läuft running oder pausiert wurde paused

Pause, Play, Playback-Rate

Beispiel 2

Die Methode play() spielt die Animtion ab, die Methode pause() pausiert.
Über die Eigenschaft playbackRate kann man die Geschwindigkeit steuern.

<button onclick="moon.pause()";>...</button>
<button onclick="moon.play()">...</button>
<button onclick="moon.playbackRate += 0.2">...</button>

Beispiel 3

Hier ein komplexeres Beispiel mit einer transform-Eigenschaft,. Bedenke, dass die CSS Eigenschaft transform: mehrere Werte bekommen kann, wie translateX() und/ oder rotate(). Diese werden nicht mit Komma getrennt aufgeführt. Weitere CSS Eigenschaften kann man komma-separiert hinzufügen.

Hier wurde eine zusätzliche Option für das Easing Verhalten eingesetzt. Das easing kann man aber auch der gesamten Animtion zuveisen, indem man es dem Timing Objekt zufügt.

let moon = document.getElementById("moonface").animate (
	[
      { transform: "translateX(0) rotate(0deg)", easing: "ease-in"},
		{ transform: "translateX(1000px) rotate(1080deg)" },
		{ transform: "translateX(0) rotate(0deg)", easing: "ease-out"}
	],
	{
		duration: 9000,
		iterations: Infinity
	}
);

Animation Ende per Event ermitteln

Mit dem Eventtype finish kann man ermitteln, ob eine Animation bis zum Ende abgelaufen ist oder mittels finish() Methode beendet wurde. Der Eventlistener muss der Animation zugewiesen werden, anstatt dem Element, welches animiert wird. Das Event finish reagiert allerdings nicht, wenn die Animation mit cancel() abgebrochen wurde. Hier müsste man den Eventtype cancel einsetzen.

var box = document.getElementById("box";)
var myAni = box.animate(boxKeys, boxTime);
myAni.addEventListener("finish", endfunktion);  

siehe Beispiel

 

Die Eigenschaft animation.playState zeigt an ob die Animtion läuft running oder pausiert wurde paused.

Die Eigenschaft animation.currentTime zeigt die Ablaufzeit in Millisekunden an.

Dom Events für CSS Animationen

Es gibt DOM Events, die auf Animationen reagieren, welche man mit CSS einem Element zugewiesen hat. Die Event-Listener werden den Elementen zugewiesen, auf welche eine @keyframe angewendet wurde.

Diese Events sollte man nicht verwechseln mit Events für Javascript Animations, wie finish, cancel.

siehe dazu W3schools

Eventtypes:

siehe Beispiel

Es gibt einige Eigenschaften, die man über den Event Parameter aufurfen kann. Siehe den Quelltext im Beispiel.

animationName

elapsedTime

pseudoElement

Bildergalerie animiert

siehe Beispiel

Diese Bildergalerie läd ein Bild nach dem anderen.

In dieser Bildergalerie gehen die Bilder scheinbar fließend ineinander über. Das geschieht durch ein langsames Ausblenden eines Bildes mittels CSS opacity. Unter dem Bild kommt das darunterliegende Hintergrundbild zum Vorschein.

Das Ende dieser Animation wird mittels Event "finish" ermittelt. Dieser Event ruft eine Funktion auf, welche die Quellen von Bild und Hintergrundbild ändern und dann wird erneut die Funktion aufgerufen, welche die Animation erneut startet um das Bild auszublenden.

Die Bilder sind namentlich durchnummeriert. Das vereinfacht die Programmierung.

Es gibt ein figure Element id="bildBack" und darin ein img id="bild". Die Breiten von figure und img werden mittels 95vh definiert.

Es gibt 23 Bilder welche mo0.jpg, mo1.jpg bis mo22.jpg heißen

Beim Start liegt mo0.jpg im img und mo1.jpg im Hintergrundbild. img wird mittels Animation und opacity ausgeblendet.

let hui = document.getElementById( "bild" ).animate( bildKeyframe, bildTiming );

Mittels Event finish wird die Funktion endeGelaende() aufgerufen.

    hui.addEventListener( "finish", endeGelaende );
    

In der Funktion ist ein etwas komplizierter Zählmechanismus, damit die Zahlen für die Bildnamen für das img und für das Hintergrundbild von figure richtig funktionieren. Das Hintergrundbild ist das nächst höhere Bild als das darüber liegende img. Wenn img.src = mo2.jpg hat, dann hat background-image mo3.jpg. Nur wenn das img die höchste Zahl erreicht hat, muss das Hintergrundbild die 0 bekommen. Anhand der Zahlen werden die Bilder zugwiesen.

 bild.src = "small/mo" + ( counter ) + ".jpg";
bildBack.style.backgroundImage = "url('small/mo" + backCount + ".jpg')";

Desweiteren gibt es noch eine Funktion playPause, welche die Animation pausiert und abspielt. Ein Klick auf das figure, ruft die Funktion auf. In der Funktion wird die Animation Eigenschaft playState aufgerufen bzw. abgefragt.

HTML

    <figure id="bildBack">
    <img src="small/mo0.jpg" alt="Monstranz" id="bild">
    </figure>
    

CSS

  body {
                background-color: black;
                color: rgb(244, 149, 7);
            }

            #bildBack {
                background-image: url("mo1.jpg");
                background-repeat:no-repeat;
                width: min-content;
                height: 95vh;
                background-size: auto 95vh;
                background-position: 50% 0;
                margin: 0;
                padding: 0;
                margin: auto;
                cursor: pointer;
                text-align: center;
            }

            img {
                height: 95vh;
            }
  

Javascript

    
         let amount = 22; //Anzahl bzw. höchste Nummer der Bilder
            let counter = 0;
            let backcount;

            let output = document.getElementById( "output" );
            let bildBack = document.getElementById( "bildBack" );

            const bildKeyframe = [
                { opacity: 1, offset: 0.5 },
                { opacity: 0 },
            ];

            const bildTiming = {
                duration: 6000,
                iterations: 1,
                fill: "forwards"
            };

            let hui = document.getElementById( "bild" ).animate( bildKeyframe, bildTiming );

            hui.play();          
            hui.addEventListener( "finish", endeGelaende );


            /* Diese Funktion wird nach Ablauf der Animation aufgerufen (EventListener "finish")
            sie wechselt das Bild und das Hintergrundbild und startet die Animation erneut
             */
            function endeGelaende ( evt )
            {
                /* counter und backCount regeln die Zahl für Bild und Hintergrundbild
                backCount ist immer ein Bild höher, nur beim letzten Bild ist es das erste.
                 */
                if ( counter < amount )
                {
                    counter++;

                } else 
                {
                    counter = 0;
                }
                backCount = counter + 1;
                if ( counter == amount )
                {
                    backCount = 0;
                }

                bild.src = "small/mo" + ( counter ) + ".jpg";
                bildBack.style.backgroundImage = "url('small/mo" + backCount + ".jpg')";
                hui.play();
            }


     bildBack.addEventListener( "click", playPause );
     function playPause(){
         if(hui.playState == "running"){
             hui.pause();
             pauseBut.innerHTML = "Play";
         }else{
             hui.play();
             pauseBut.innerHTML = "Pause";
         }
     }
    

Komplexes Beispiel

Beispiel 4

In diesem Beispiel wird die Strecke anhand der Fensterbreite ermittelt. Damit wird dann auch die Anzahl der Umdrehungen und die Dauer der Animation berechnet.

        let width = window.innerWidth;
        let elemWidth = document.getElementById("moon").offsetWidth;
        let circumfence = elemWidth * Math.PI;
        let umdrehungen = parseInt(width / circumfence);
        let duration = width * 10;
        let rotate = duration / 1000 / umdrehungen;

        let wheel = document.getElementById("moon").animate(
            [{
                transform: "translateX(0) rotate(0deg)",
                easing: "ease-in"
            }, {
                transform: "translateX(" +( width-elemWidth) + "px) rotate(" + (umdrehungen * 360) + "deg)"
            }, {

                transform: "translateX(0) rotate(0deg)",
                easing: "ease-out"
            }], {
                duration: duration,
                iterations: Infinity
            }
        );
  

Javascript Tipps