Start · Sprachen · JavaScript · Referenz · Animation.finish()

Animation.finish()

Methode

Springt sofort ans Ende einer Animation, und zwar in der aktuellen Wiedergaberichtung. Das Ende hängt also vom Vorzeichen von <code>playbackRate</code> ab.

seit JavaScript Baseline: alle modernen Browser (seit 2020) Kategorie: webapi

Signatur

Animation.prototype.finish()

Beschreibung

Die Methode finish() gehört zum Animation-Interface der Web Animations API. Sie setzt currentTime direkt auf das Ende der Animation. Bei positiver playbackRate ist das das Ende des Effekts: Verzögerung + Dauer × Wiederholungen + Endverzögerung. Bei negativer playbackRate (rückwärts) ist es der Wert 0. Die Animation ist danach im Zustand playState === "finished".

Typische Einsatzfälle:

  • ein Knopf „Animation überspringen“
  • Rücksicht auf prefers-reduced-motion
  • Tests, die sofort den Endzustand prüfen wollen
  • Übergänge abbrechen, wenn schnell nacheinander Benutzeraktionen kommen

Beim Aufruf passiert Folgendes: Das Promise animation.finished wird erfüllt (resolved) und das Ereignis finish wird ausgelöst. Beides passiert asynchron, im nächsten Mikrotask bzw. Animationsframe. Ist die Animation pausiert oder wartet sie noch auf ihren Start (pending), bringt finish() sie trotzdem in den beendeten Zustand. Eine noch ausstehende Pause wird dabei verworfen.

Ob der Endzustand danach sichtbar bleibt, hängt von der Option fill ab. Nur mit fill: "forwards" oder "both" bleibt der letzte Keyframe stehen. Ohne diese Option springt das Element nach finish() in seinen ursprünglichen Stil zurück.

Rückgabewert

Typ
void
Beschreibung
Kein Rückgabewert (undefined). Um auf das Ende zu reagieren, nutzt man animation.finished oder das Ereignis finish.

Beispiele

Knopf „Überspringen“ für eine Intro-Animation

const logo = document.querySelector('#logo');
const skipBtn = document.querySelector('#skip');

const intro = logo.animate(
  [
    { opacity: 0, transform: 'scale(0.5)' },
    { opacity: 1, transform: 'scale(1)' }
  ],
  { duration: 3000, easing: 'ease-out', fill: 'forwards' } // fill hält den Endzustand
);

skipBtn.addEventListener('click', () => {
  intro.finish(); // springt sofort auf opacity 1 / scale 1
});

intro.finished.then(() => {
  console.log('Intro beendet:', intro.playState);
});
Intro beendet: finished

Rückwärts laufende Animation beenden

const box = document.querySelector('.box');
const anim = box.animate(
  [{ transform: 'translateX(0)' }, { transform: 'translateX(300px)' }],
  { duration: 1000, fill: 'both' }
);

anim.reverse();   // playbackRate wird -1
anim.finish();    // Ende in Rückwärtsrichtung = Zeitpunkt 0

console.log(anim.currentTime, anim.playState);
0 finished

Reduzierte Bewegung respektieren und Fehler abfangen

const prefersReduced = matchMedia('(prefers-reduced-motion: reduce)').matches;

const finishSafely = (animation) => {
  try {
    animation.finish();
  } catch (err) {
    // InvalidStateError bei playbackRate 0 oder endloser Animation
    console.warn('finish() nicht möglich:', err.name);
    animation.cancel();
  }
};

const spinner = document.querySelector('.spinner').animate(
  [{ rotate: '0deg' }, { rotate: '360deg' }],
  { duration: 800, iterations: Infinity }
);

if (prefersReduced) {
  finishSafely(spinner);
}
finish() nicht möglich: InvalidStateError

Alle laufenden Animationen eines Elements sofort abschließen

const panel = document.querySelector('.panel');

const completeAll = async (el) => {
  const animations = el.getAnimations();
  animations.forEach((a) => a.finish());
  await Promise.all(animations.map((a) => a.finished));
  console.log(`${animations.length} Animation(en) abgeschlossen`);
};

completeAll(panel);
2 Animation(en) abgeschlossen

// Wichtig · Fallstricke

  • InvalidStateError: Die Methode wirft diesen Fehler in zwei Fällen:
    • playbackRate ist 0.
    • playbackRate ist positiv und das Ende ist unendlich, z. B. bei iterations: Infinity.
    Für Endlos-Animationen ist cancel() meist die bessere Wahl.
  • Endzustand verschwindet: Ohne fill: "forwards"/"both" wirkt der Effekt nach finish() nicht mehr. Das Element springt dann in seinen ursprünglichen Stil zurück. Alternativ übernimmt man den Endwert mit commitStyles() fest in den Stil des Elements.
  • Asynchrone Benachrichtigung: finished und das Ereignis finish werden nicht synchron innerhalb von finish() ausgelöst. Code, der auf den Abschluss reagiert, gehört in .then() bzw. den Event-Handler.
  • Unterschied zu cancel(): finish() springt ans Ende und erfüllt das Promise finished. cancel() entfernt dagegen alle Effekte und lehnt finished mit einem AbortError ab.
  • Kompatibilität: Wird in Chrome, Edge, Firefox und Safari (ab 13.1) unterstützt. Das gilt auch für CSS-Animationen und -Transitions, die man über element.getAnimations() erhält.