1 Punkte von GN⁺ 2024-03-09 | 1 Kommentare | Auf WhatsApp teilen

Animationstricks mit Exponential Smoothing

  • Seit ich angefangen habe, an animationsbezogenen Dingen zu arbeiten, gibt es eine einfache Animationstechnik, die ich fast immer verwendet habe.
  • Diese Technik wird an vielen Stellen eingesetzt, etwa bei Kamerarotation und -bewegung, der Figurenbewegung in rundenbasierten Spielen, der Bewegung von UI-Elementen oder der Glättung von Lautstärkeänderungen in Audio-Bibliotheken.
  • Die Technik ist nicht neu; vielleicht hast du schon davon gehört oder sie selbst verwendet. Ich werde aber einige Beispiele und die mathematischen Grundlagen erklären.

Toggle-Button

  • Nehmen wir an, wir bauen eine UI-Komponente, zum Beispiel einen Toggle-Button.
  • Die Position des Schalters im Toggle-Button wird abhängig vom Zustand berechnet und auf max_x gesetzt, wenn er eingeschaltet ist, und auf min_x, wenn er ausgeschaltet ist.
  • Das funktioniert gut, wirkt ohne Animation aber etwas leblos.
  • Animation sorgt nicht nur für visuelle Eleganz, sondern hilft Nutzern auch zu verstehen, was gerade passiert.
  • Statt den Toggle-Indikator sofort an die neue Position zu setzen, ändern wir ihn so, dass er sich sanft bewegt.
  • Jetzt muss die Animation aktualisiert werden, was den Nachteil hat, dass die Bewegung wie mit konstanter Geschwindigkeit aussieht.
  • Man kann hier eine Easing-Funktion hinzufügen und zum Beispiel 3t^2-2t^3 oder sqrt(t) verwenden.
  • Die Unterschiede zwischen solchen Easing-Funktionen sieht man besser, wenn man die Animation verlangsamt.
  • Jetzt muss man statt nur die Schalterposition zu aktualisieren auch den Animationszustand nachverfolgen.
  • Wenn man sqrt verwendet, muss man abhängig von der Animationsrichtung explizit unterschiedliche Easing-Funktionen einsetzen.
  • Was am besten aussieht, ist Geschmackssache, aber sqrt sieht am besten aus. Der Schalter startet damit sehr schnell und wird beim Annähern an das Ziel schön langsamer.
  • Der Nachteil dieser Version ist, dass selbst der einfachste Fall ziemlich viel Verwaltungsaufwand erfordert und dass es eine sprunghafte Diskontinuität gibt, wenn der Nutzer mitten in der Animation klickt.

Kamerabewegung

  • Nehmen wir an, eine Karte und eine Kamera scrollen oder bewegen sich durch die Umgebung.
  • Auch hier ist es gut, Animation hinzuzufügen.
  • Es wird Code gezeigt, der mit konstanter Geschwindigkeit interpoliert.
  • Das Zittern nach Abschluss der Animation entsteht, weil target.x - position.x abwechselnd positiv und negativ wird.
  • Statt sign(delta) braucht man eine Funktion, die das Delta clampt.
  • Diese Methode ist für etwas Einfaches ziemlich kompliziert.
  • Es sieht seltsam aus, wenn die Animationsgeschwindigkeit höher ist als das Erreichen des Animationsendes.
  • Man könnte die Eingaben des Nutzers ignorieren, solange die Animation aktiv ist, aber das wäre eine sehr frustrierende Nutzererfahrung.
  • Die perfekte Lösung ist natürlich Exponential Smoothing.
  • Im Vergleich zum Toggle-Button-Beispiel ändert sich der Code kaum.

Wie es intern funktioniert

  • Es wird erklärt, was 1 - exp(- speed * dt) ist und wie es funktioniert.
  • Zunächst wird mit einer einfachen Version begonnen, bei der die Bewegungsgeschwindigkeit proportional zur Distanz zwischen der aktuellen position und der neuen Zielposition target gemacht wird.
  • Diese Methode braucht keinen weiteren Zustand außer aktueller Position und Zielposition und passt sich automatisch an, selbst wenn sich target plötzlich ändert.
  • Es gibt jedoch ein kleines Problem: Wenn speed * dt größer als 1 ist, schießt die Position über das Ziel hinaus.
  • Um dieses Problem zu lösen, kann man den Wert auf 1 clampen.
  • Der Grund, warum speed * dt zu groß wird, ist entweder ein zu großer speed-Wert oder ein zu großes dt.
  • Für Animationen wäre es schön, wenn beim Anwenden von dt alles perfekt funktionieren würde.

Differentialgleichungen (oh nein)

  • Es wird ein zweistufiger Ansatz vorgestellt, um das Problem zu lösen.
  • Dass position += (target - position) * speed * dt für kleine dt funktioniert, aber für große dt versagt, ist ein typisches Problem numerischer Lösungen von Differentialgleichungen.
  • Es wird untersucht, was diese Gleichung eigentlich löst.
  • Es wird erklärt, dass position += (target - position) * (1 - exp(- speed * dt)) die korrekte Formel für alle dt ist.

Wahl der Geschwindigkeit

  • Normalerweise denkt man bei Animationen in Dauerangaben.
  • Mit der Exponentialformel wird eine Animation technisch gesehen erst nach unendlicher Zeit vollständig abgeschlossen.
  • Die Bedeutung des Parameters speed ist, dass 1 / speed die Zeit ist, in der position dem target um den Faktor e = 2.71828... näher kommt.

Exponential Smoothing

  • Wenn man nach „Exponential Smoothing“ sucht, findet man möglicherweise einen Wiki-Artikel, der völlig unrelated wirkt, tatsächlich aber eine Formel enthält, die der in diesem Beitrag sehr ähnlich ist.
  • Wenn man annimmt, dass dt immer gleich bleibt und sich target bei jeder Iteration ändert, kann man die Werte über die Iterationsnummer indizieren und etwas wie position[i] = (target[i] - position[i - 1]) * factor berechnen.

Titel des letzten Absatzes

  • Ich hatte die Idee zu diesem Beitrag schon seit einigen Monaten und freue mich, ihn endlich fertiggestellt zu haben.
  • Danke fürs Zuschauen des Devlogs und fürs Lesen.

Meinung von GN⁺

  • Dieser Artikel erklärt die Technik des Exponential Smoothing, die verwendet wird, um Animationen weich und natürlich wirken zu lassen. Sie trägt dazu bei, die User Experience zu verbessern und die Intuitivität von Interfaces zu erhöhen.
  • Exponential Smoothing kann auch nützlich sein, um physische Bewegungen zu simulieren, etwa in der Spieleentwicklung, um Figurenbewegungen oder Kamerafahrten natürlicher wirken zu lassen.
  • Die Technik ist besonders wirksam, wenn Elemente einer Benutzeroberfläche Zustandsänderungen durchlaufen und diese visuell dargestellt werden sollen. Zum Beispiel kann die Bewegung von Slidern oder Schaltern deutlich sanfter erscheinen.
  • Kritisch betrachtet kann Exponential Smoothing es schwieriger machen, Geschwindigkeit und Dauer von Animationen exakt zu steuern. Das kann einschränkend sein, wenn Designer einen bestimmten Animationseffekt sehr präzise abstimmen wollen.
  • Andere Animationsbibliotheken oder Frameworks mit ähnlicher Funktionalität sind etwa GreenSock Animation Platform (GSAP) oder anime.js; sie bieten zusammen mit verschiedenen Easing-Funktionen eine feinere Kontrolle über Animationen.
  • Bei der Einführung von Exponential Smoothing sollte man ein Gleichgewicht zwischen natürlicher Wirkung und präziser Steuerbarkeit finden. Der Vorteil ist eine bessere User Experience, der Nachteil kann die schwierigere Feinabstimmung des Timings sein.

1 Kommentare

 
GN⁺ 2024-03-09
Hacker-News-Kommentare
  • Zusammenfassung des ersten Kommentars:

    • Es wird betont, dass diese Methode keine einfache Easing-Kurve oder smoothstep()-Funktion ist, sondern ein zustandsloser Ansatz, der unterschiedliche Eingaben konsistent verarbeitet.
    • Wer Erfahrung mit CSS-Transitions hat, kann das Problem verstehen, das diese Technik löst.
    • Exponentielle Glättung hat das Problem, sich dem Ziel anzunähern, es aber nie wirklich zu erreichen.
    • Es wird erwähnt, dass es nützlich war, bei der Verwendung einer ähnlichen Methode für träges Scrollen einen (künstlichen) Reibungsterm hinzuzufügen.
  • Zusammenfassung des zweiten Kommentars:

    • Als Spieleentwickler bevorzugt der Kommentator in den meisten UI-Situationen Easing-Tweens mit fest vorgegebener Dauer.
    • Diese Technik ist jedoch sehr nützlich, wenn kontinuierliche und unvorhersehbare Bewegungen geglättet werden sollen, bei denen Anfangs- und Endpunkt nicht klar sind.
    • Exponentielles Lerp ist nützlich, aber nicht weithin bekannt, und einige Spiele leiden unter Animationsproblemen, weil sie stattdessen weniger präzise lineare Interpolation verwenden.
    • Aus diesen Gründen bedankt sich der Kommentator für den Artikel, da solcherlei spezifisches Wissen oft schwer zugänglich ist.
  • Zusammenfassung des dritten Kommentars:

    • Es wird Widerspruch gegen die Behauptung des Autors eingelegt, dass bei Kippschaltern die Quadratwurzel (sqrt) besser sei als kubisch.
    • Unter Berücksichtigung der Funktionsweise realer Kippschalter wird argumentiert, dass eine kubische Funktion geeigneter sei.
    • Der Artikel wird als gutes Beispiel dafür bewertet, wie Animationen die User Experience verbessern können.
  • Zusammenfassung des vierten Kommentars:

    • Es wird Bewunderung für einfache nichtlineare Tricks ausgedrückt, die Online-Interaktionen angenehmer machen.
    • Es wird erwähnt, dass dies bei der Farbwahrnehmung eine wichtige Rolle spielt und dass Menschen Beschleunigung nicht immer intuitiv verstehen.
  • Zusammenfassung des fünften Kommentars:

    • Der Artikel gefällt dem Kommentator, und er erwähnt, dieselbe Technik bereits vor fast zehn Jahren unter dem Namen "lazy-easy" beschrieben zu haben.
    • Er sagt, dass er sie immer noch verwendet, wenn er sanfte Animationen ohne Zustandsverwaltung haben möchte.
  • Zusammenfassung des sechsten Kommentars:

    • Es wird angemerkt, dass Artikel über Easing in jeder Generation neu entdeckt zu werden scheinen.
    • Es wird daran erinnert, dass die experimentellen Websites von Yugo Nakamura in den späten 90ern zu den ersten gehörten, die Easing frei einsetzten und dadurch ein organisches Gefühl erzeugten.
  • Zusammenfassung des siebten Kommentars:

    • Es wird die Idee für einen Schalter vorgeschlagen, der sich langsam bewegt, solange man die Berührung bzw. den Klick hält, und nach dem Loslassen den Rest schnell einrastet.
    • Der Kommentator ist sich nicht sicher, was das aus UX-Sicht bedeutet, hält es aber für möglich, dass dies anzeigen könnte, wann eine Einstellung angewendet oder gespeichert wird.
  • Zusammenfassung des achten Kommentars:

    • Diese Technik wird nicht nur für Schalter, sondern für viele verschiedene Anwendungsfälle als nützlich eingeschätzt.
    • Es wird eine Demo im Zusammenhang mit Flickity erwähnt, und es wird darauf hingewiesen, dass diese Technik nicht viele der für Production-Readiness nötigen Optimierungen enthielt.
    • Der Kommentator kritisiert, dass die Leute in den Kommentaren den Artikel entweder nicht richtig gelesen haben oder wichtige Punkte übersehen.
  • Zusammenfassung des neunten Kommentars:

    • Der Artikel wird positiv bewertet, und es wird erwähnt, dass die Demo in Chrome gut funktioniert, in Firefox jedoch die Seite einfriert.
  • Zusammenfassung des zehnten Kommentars:

    • Kleine Animationen werden als höchste Form emotionalen Designs beschrieben, die sehr viel ausdrücken können.