S SvelteKurs
M6 · Transitions & Animationen

Animationen & Motion

animate:flip animiert Positionswechsel in Listen, und Tween/Spring animieren einzelne Werte weich über die Zeit.

animate:flip — sanftes Umsortieren

Transitions animieren Ein- und Ausblenden. Animationen mit animate:flip kümmern sich um etwas anderes: wenn ein Element in einer {#each}-Liste seine Position wechselt. FLIP steht für „First, Last, Invert, Play" — Svelte misst die alte und die neue Position und animiert die Differenz.

Sortierliste.svelte svelte
<script>
  import { flip } from 'svelte/animate';
  let liste = $state([{ id: 1, ... }, ...]);
</script>

<ul>
  {#each liste as item (item.id)}   <!-- KEY ist Pflicht! -->
    <li animate:flip={{ duration: 300 }}>{item.name}</li>
  {/each}
</ul>

⚠️ Ohne KEY kein flip

animate:flip funktioniert nur mit einem stabilen KEY im {#each list as item (item.id)}. Der Key sagt Svelte, welches DOM-Element zu welchem Datensatz gehört — sonst kann es Positionen nicht zuordnen.

js
// animate:flip reagiert nur, wenn sich die REIHENFOLGE
// der Elemente ändert — nicht beim Hinzufügen/Entfernen.
// Deshalb sortieren wir das Array neu (nicht filtern):
team = [...team].sort(() => Math.random() - 0.5);

Live: umsortierbare Liste

Verschiebe Einträge oder mische die ganze Liste — jede Positionsänderung wird animiert.

▶ animate:flip · Interaktiv
  • Anna
  • Bruno
  • Clara
  • David

Motion: Tween für weiche Werte

Manchmal willst du keinen Ein-/Ausblend-Effekt, sondern einen Zahlenwert weich von A nach B laufen lassen — etwa einen Fortschrittsbalken. In Svelte 5 nutzt du dafür die Klasse Tween aus svelte/motion: Du setzt das Ziel über .target und liest den animierten Wert über .current.

Fortschritt.svelte svelte
<script>
  import { Tween } from 'svelte/motion';
  import { cubicOut } from 'svelte/easing';

  // Svelte 5: Klasse statt Store
  const fortschritt = new Tween(20, { duration: 500, easing: cubicOut });

  function zufall() {
    fortschritt.target = Math.round(Math.random() * 100); // Ziel setzen
  }
</script>

<div style="width: {fortschritt.current}%">…</div>  <!-- .current lesen -->
▶ Tween-Fortschrittsbalken · Interaktiv
20%

🛤️ Rails-Vergleich: keine Entsprechung

Für so etwas gibt es in Rails/Turbo keine Entsprechung. Einen weich zählenden Balken baust du dort von Hand — mit CSS-Transitions plus Stimulus-Controller, der Zielwerte setzt und die Breite steuert. Svelte gibt dir das mit einer Zeile new Tween(…).

Motion: Spring für Physik-Gefühl

Spring funktioniert wie Tween, animiert aber nicht zeit-, sondern federbasiert: Der Wert schwingt sich elastisch auf sein Ziel ein. Ideal für Interaktionen, die „lebendig" wirken sollen.

spring.ts ts
import { Spring } from 'svelte/motion';

const groesse = new Spring(60, { stiffness: 0.1, damping: 0.4 });

// Wie Tween, aber physikbasiert (federnd) statt zeitbasiert:
groesse.target = 120;      // schwingt sich auf den Wert ein
groesse.current;           // aktueller, animierter Wert
▶ Spring: elastischer Kreis · Interaktiv

Zusammenfassung

💡 Das Wichtigste

  • animate:flip animiert Positionswechsel in {#each} — KEY ist Pflicht.
  • Es reagiert auf Reihenfolge-Änderungen, nicht auf Hinzufügen/Entfernen (dafür sind Transitions da).
  • new Tween(wert, opts): .target setzen, .current lesen.
  • new Spring(wert, opts): dasselbe Muster, aber physikalisch federnd.

🎯 Probier es selbst

Kombiniere beides: Gib den Listeneinträgen zusätzlich ein transition:fade und einen Button zum Hinzufügen. Beobachte, wie flip die verbleibenden Einträge verschiebt, während der neue einblendet.