How to: den Ball ins Rollen bringen!

Nachdem ich in meinem letzten Logbucheintrag sehr viel über Animationen geschrieben habe, werde ich in diesem Sachbeitrag die technischen Aspekte von Animationen beleuchten.

In der Webentwicklung kann man sowohl mit CSS als auch mit Javascript animieren. Die Ansätze variieren jedoch teilweise stark.

Beginnen wir mit der, meiner Meinung nach, einfacheren Methode über CSS.

Dort lassen sich Animationen mit der @keyframe Regel definieren und können entweder von Anfang bis Ende linear animiert werden oder über Prozentangaben nicht linear.

Und genau da liegt der Hund begraben.

Durch die Prozentangaben setzt man Keyframes, wodurch komplexere Animationen möglich sind. Es gibt eine Reihe von Funktionen, um etwas zu animieren.

Für das lineare Animieren muss lediglich der Anfang und das Ende definiert werden.

Jedoch möchte man oft komplexere Animationen durchführen. Wenn im Bild ein Ball z. B. fällt, soll diese beim Fallen beschleunigen, auf dem „Boden" abprallen und einen „Bounce" Effekt haben. Solche Animationen sind linear unmöglich zu erstellen. Dafür braucht man komplexere Verlangsamungs-Funktionen ("easing Functions"). Eine Auswahl von solchen Funktionen findet man z. B. auf https://easings.net/.

Natürlich kann man diese Animationen auch selbst von „Hand" schreiben. Dazu muss man die Animation in einzelne, möglichst lineare Abschnitte einteilen und die entsprechenden Schlüsselbilder definieren. Daher auch der Name „Keyframe".

Ein faszinierendes Beispiel findet ihr in diesem Beitrag: https://nrml.de/blog/happy-halloween.

Neben der CSS Methode über Keyframes findet man auch die Javascript Funktionen dazu.

Um genauer zu verstehen, wie Animationen in Javascript funktionieren, gehen wir einen Schritt zurück zu den linearen Funktionen und schreiben eine simple Animation.

Die Funktion heißt lineare Interpolation (kurz Lerp). Unsere Lerp-Funktion ist auch relativ einfach a+(b-a)*t. 

Aber bevor wir es verwenden, brauchen wir zwei Punkte, zwischen denen wir interpolieren wollen. Dazu nehmen wir mal Punkt A und B, das kann auf einer Webseite natürlich alles Mögliche sein. 

Diese Punkte haben jeweils zwei Werte für die x- und y-Achse. Um es einfach zu halten, bleiben wir auf der x-Achse und geben die x-Achsen Werte der Funktion (function lerp (A.x,B.x,t)). 

Was noch fehlt, ist t. Der Wert für t beschreibt den „Fortschritt". Ein t-Wert von 0 würde genau auf Punkt A liegen und bei einem t-Wert von 1 landen wir punktgenau auf B. 

Sobald wir die Funktion in einer Schleife aufrufen und den t-Wert von der Schleifenvariable abhängig machen, haben wir unsere Animation.

Anstelle einer primitiven Schleife verwenden wir die Funktion "requestAnimationFrame()" und machen unseren t-Wert von der Zeit abhängig. Dadurch erreichen wir, dass die Animation gleichmäßig läuft und entlasten den Browser, da die "requestAnimationFrame()" Funktion durch Callbacks aufgerufen wird und auf Schleifen verzichtet.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Animation
    </title>
</head>
<body>
    <Canvas class="meinCanvas"></Canvas>
 
<script>
// Als Erstes erstellen wir eine Canvas Fläche auf die wir „malen“ können
    const meinCanvas = document.querySelector(".meinCanvas");
    meinCanvas.width = window.innerWidth;
    meinCanvas.height = window.innerHeight;
 
    const ctx = meinCanvas.getContext("2d");
// Hier definieren wir uns unsere Punkte, wobei wir C null als x wert geben
    const A ={x:150,y:100};
    const B ={x:550,y:100};
    const C ={x:0,y:100};
 
// Mit der zeichnePunkt Funktion Malen wir unsere Punkte auf unser Canvas 
 
    zeichnePunkt(A,"A");
    zeichnePunkt(B,"B");
 
// Zuletzt rufen wir die animiere Funktion auf. 
// Hier passiert die ganze Magie.
 
    animiere();
 
    function animiere(){
// In der Funktion löschen wir als Erstes alles auf unserem Canvas
        ctx.clearRect(0,0,meinCanvas.width,meinCanvas.height);
// Dann nehmen wir uns die Uhrzeit und schreiben den Bruchteil der 
// aktuellen Sekunde in t rein.
        const sekunde = new Date().getTime()/1000;
        const t=sekunde-Math.floor(sekunde);
// Hier nutzen wir die lerp Funktion, um den X Wert von C zu generieren und
// zeichnen alle Punkte auf unser Canvas.
        C.x = lerp (A.x,B.x,t);
        zeichnePunkt(C,"C");
 
        zeichnePunkt(A,"A");
        zeichnePunkt(B,"B");
// Am Ende nutzen wir die “requestAnimationFrame” Funktion um die Animation
// zu wiederholen, so können wir auf eine Schleife verzichten.
        requestAnimationFrame(animiere);
    }
 
 
// Hier haben wir unsere lerp Funktion relativ simple definiert
    function lerp (a,b,t){
        return a+(b-a)*t;
    }
// Die “zeichnePunkt” Funktion funktioniert nur um ins Canvas zu „malen“. 
    function zeichnePunkt(position,name){
       
        ctx.beginPath();
        ctx.fillStyle = "aqua";
        ctx.strokeStyle="black";
        ctx.arc(position.x,position.y,10,0,Math.PI*2);
        ctx.fill();
        ctx.stroke();
        ctx.fillStyle="black";
        ctx.textAlign="center";
        ctx.textBaseline="middle";
        ctx.font = "bold"
        ctx.fillText(name,position.x,position.y);
}
</script>
 
</body>
</html>
 
Animation

Noch mehr über Animationen findet ihr hier:

https://nrml.de/blog/css-animation

https://nrml.de/blog/lottie-files


Titelbild von jbauer-fotographie auf Pixabay

By accepting you will be accessing a service provided by a third-party external to https://nrml.de/