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

Animation.reverse()

Methode

Kehrt die Abspielrichtung einer <code>Animation</code> um, sodass sie rückwärts zu ihrem Anfang läuft, und startet sie bei Bedarf.

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

Signatur

Animation.prototype.reverse()

Beschreibung

reverse() gehört zur Web Animations API und kehrt die Abspielrichtung einer Animation um. Technisch wird die Wiedergaberate (playbackRate) negiert, aus 1 wird also -1, aus -2 wird 2. Danach wird die Animation wie bei play() gestartet. Eine rückwärts laufende Animation endet an ihrem Anfang (currentTime = 0).

Die Methode eignet sich gut für umkehrbare Zustände wie Menüs auf- und zuklappen, Hover-Effekte oder Akkordeons. Wird die Richtung mitten in der Animation gewechselt, läuft sie von der aktuellen Position aus zurück, ohne zu springen. Das wirkt deutlich flüssiger als eine zweite, gespiegelte Animation.

Wichtig ist das Verhalten an den Rändern:

  • Ist die Animation pausiert, wird sie durch reverse() fortgesetzt, und zwar in umgekehrter Richtung.
  • Ist sie beendet (playState === "finished") oder hat sie noch nicht begonnen, springt sie automatisch an das passende Ende und läuft von dort zurück.
  • Die neue Wiedergaberate wird zunächst als ausstehend vorgemerkt und gilt ab dem nächsten Bereitschaftszeitpunkt (animation.ready).

Rückgabewert

Typ
void
Beschreibung
Kein Rückgabewert (undefined). Wann die Animation tatsächlich läuft, erfährst du über das Promise animation.ready, ihr Ende über animation.finished.

Beispiele

Menü per Knopf auf- und zuklappen

const menu = document.querySelector('#menu');
const button = document.querySelector('#toggle');

// Animation einmal anlegen und sofort pausieren
const anim = menu.animate(
  [
    { transform: 'translateY(-100%)', opacity: 0 },
    { transform: 'translateY(0)', opacity: 1 }
  ],
  { duration: 300, easing: 'ease-out', fill: 'both' }
);
anim.pause();

let offen = false;
button.addEventListener('click', () => {
  if (!offen) {
    anim.playbackRate = 1;
    anim.play();
  } else {
    anim.reverse(); // läuft von der aktuellen Position zurück
  }
  offen = !offen;
});

Wiedergaberate vor und nach reverse() prüfen

const box = document.querySelector('.box');
const anim = box.animate(
  [{ transform: 'scale(1)' }, { transform: 'scale(1.5)' }],
  { duration: 1000, fill: 'forwards' }
);

anim.playbackRate = 2;
console.log(anim.playbackRate);

anim.reverse();
await anim.ready; // ausstehende Rate ist jetzt angewendet
console.log(anim.playbackRate, anim.playState);
2 -2 running

Hin-und-her-Effekt mit dem finished-Promise

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

const pingPong = async (durchlaeufe) => {
  for (let i = 0; i < durchlaeufe; i++) {
    await anim.finished;
    anim.reverse(); // beendete Animation startet am Ende neu, rückwärts
  }
  await anim.finished;
  console.log('fertig, playbackRate =', anim.playbackRate);
};

pingPong(3);
fertig, playbackRate = -1

Hover-Effekt, der sanft zurückläuft

const card = document.querySelector('.card');
const hover = card.animate(
  [{ boxShadow: '0 0 0 rgba(0,0,0,0)' }, { boxShadow: '0 8px 24px rgba(0,0,0,.3)' }],
  { duration: 250, fill: 'both' }
);
hover.pause();

card.addEventListener('mouseenter', () => {
  if (hover.playbackRate < 0) hover.reverse();
  else hover.play();
});
card.addEventListener('mouseleave', () => {
  if (hover.playbackRate > 0) hover.reverse();
  else hover.play();
});

// Wichtig · Fallstricke

  • Umschalten statt setzen: reverse() kehrt die Richtung jedes Mal um. Wer sie zweimal aufruft, landet wieder bei der ursprünglichen Richtung. Wenn du eine feste Richtung brauchst, prüfe vorher das Vorzeichen von playbackRate oder nutze updatePlaybackRate(-1).
  • Endlose Animationen: Bei iterations: Infinity hat die Animation kein Ende, an das sie springen könnte. Ein reverse() aus dem Leerlauf oder dem Anfangszustand wirft deshalb eine InvalidStateError-DOMException.
  • Keine Zeitleiste: Hat die Animation keine Zeitleiste (timeline === null) oder ist diese inaktiv, wirft die Methode ebenfalls eine InvalidStateError.
  • Asynchrone Übernahme: Die neue Rate wird erst mit animation.ready sicher übernommen. Werte, die du direkt nach dem Aufruf ausliest, können noch den alten Stand zeigen.
  • fill-Modus: Ohne fill: 'both' bzw. 'backwards' springt das Element nach dem Rücklauf auf seinen ursprünglichen CSS-Zustand zurück. Das ist oft gewollt, kann aber flackern.
  • Kompatibilität: Wird von allen modernen Browsern unterstützt (Chrome/Edge, Firefox, Safari 13.1+). Im Internet Explorer gibt es die Methode nicht.