Start · Sprachen · JavaScript · Referenz · AnimationEffect

AnimationEffect

Schnittstelle

Abstrakte Basisschnittstelle der Web Animations API, die das Timing eines Animationseffekts beschreibt – konkret umgesetzt durch <code>KeyframeEffect</code>.

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

Signatur

interface AnimationEffect

Beschreibung

AnimationEffect ist die abstrakte Basisschnittstelle für alle Animationseffekte der Web Animations API. Sie legt fest, wann und wie lange ein Effekt läuft (Dauer, Verzögerung, Wiederholungen, Richtung, Easing, Füllmodus), aber nicht, was animiert wird. Das übernimmt die einzige konkrete Unterklasse KeyframeEffect, die zusätzlich Zielelement und Keyframes enthält.

Instanzen erzeugt man nicht direkt, denn new AnimationEffect() wirft einen TypeError. Man bekommt sie über new KeyframeEffect(...) oder über die Eigenschaft animation.effect einer Animation, die zum Beispiel Element.prototype.animate() zurückgibt. Auch CSS-Animationen und -Transitions stellen über document.getAnimations() ihre Effekte bereit.

Die Schnittstelle bietet drei Methoden:

  • getTiming() gibt die festgelegten Timing-Eigenschaften als Objekt zurück (EffectTiming: duration, delay, endDelay, iterations, iterationStart, direction, easing, fill).
  • getComputedTiming() gibt die berechneten Laufzeitwerte zurück (ComputedEffectTiming), darunter progress, currentIteration, localTime, activeDuration und endTime.
  • updateTiming(timing) ändert einzelne Timing-Werte, während die Animation läuft.

Typische Einsatzfälle: den Fortschritt einer Animation auslesen (etwa für Fortschrittsbalken oder synchronisierte Effekte), die Dauer oder Wiederholungszahl nachträglich ändern oder den Effekt einer Animation austauschen.

Rückgabewert

Typ
EffectTiming | ComputedEffectTiming | void
Beschreibung
getTiming() gibt ein EffectTiming-Objekt zurück, getComputedTiming() ein ComputedEffectTiming-Objekt, updateTiming() gibt undefined zurück.

Beispiele

Effekt über Element.animate() abrufen und Timing lesen

const box = document.querySelector('.box');
const animation = box.animate(
  [{ transform: 'translateX(0)' }, { transform: 'translateX(300px)' }],
  { duration: 1000, iterations: 3, easing: 'ease-in-out' }
);

// animation.effect ist ein KeyframeEffect und damit auch ein AnimationEffect
const effect = animation.effect;
console.log(effect instanceof AnimationEffect);
const { duration, iterations, easing } = effect.getTiming();
console.log(duration, iterations, easing);
true 1000 3 ease-in-out

Fortschritt mit getComputedTiming() anzeigen

const bar = document.querySelector('#progress');
const anim = document.querySelector('.loader').animate(
  [{ opacity: 0 }, { opacity: 1 }],
  { duration: 2000, fill: 'forwards' }
);

const tick = () => {
  const { progress, currentIteration } = anim.effect.getComputedTiming();
  if (progress !== null) {
    bar.value = Math.round(progress * 100);
    console.log(`Durchlauf ${currentIteration}: ${bar.value} %`);
  }
  if (anim.playState !== 'finished') requestAnimationFrame(tick);
};
requestAnimationFrame(tick);
Durchlauf 0: 3 % Durchlauf 0: 5 % … (bis 100 %)

Timing mit updateTiming() zur Laufzeit ändern

const spinner = document.querySelector('.spinner');
const effect = new KeyframeEffect(
  spinner,
  [{ transform: 'rotate(0deg)' }, { transform: 'rotate(360deg)' }],
  { duration: 1500, iterations: 1 }
);
const animation = new Animation(effect, document.timeline);
animation.play();

// Z. B. solange ein Ladevorgang dauert: endlos und schneller drehen
effect.updateTiming({ duration: 600, iterations: Infinity });
console.log(effect.getTiming().iterations);

// Nach dem Laden: nach dem aktuellen Durchlauf beenden
const finishSoon = () => {
  const { currentIteration } = effect.getComputedTiming();
  effect.updateTiming({ iterations: currentIteration + 1 });
};
setTimeout(finishSoon, 3000);
Infinity

Effekte von CSS-Animationen auswerten

// Läuft bereits eine CSS-Animation (@keyframes), kann man ihren Effekt ebenfalls auslesen
for (const anim of document.getAnimations()) {
  const { activeDuration, endTime } = anim.effect.getComputedTiming();
  console.log(anim.animationName ?? anim.id, activeDuration, endTime);
}
fade-in 500 500

// Wichtig · Fallstricke

  • Abstrakte Schnittstelle: new AnimationEffect() wirft einen TypeError. Verwende stattdessen new KeyframeEffect() oder Element.prototype.animate().
  • Timing-Daten sind Kopien: getTiming() liefert eine Kopie. Direkte Änderungen am zurückgegebenen Objekt wirken sich nicht aus, dafür braucht man updateTiming().
  • progress kann null sein: Außerhalb der aktiven Phase (etwa während delay ohne passenden fill-Modus oder nach dem Ende bei fill: 'none') sind progress und currentIteration null.
  • Einheit: Zeitangaben sind in Millisekunden. duration kann auch 'auto' sein; das entspricht 0 bzw. bei Scroll-Timelines der Länge der Timeline.
  • CSS-Animationen: Mit updateTiming() kann man auch CSS-Animationen verändern. Ab dann überschreiben diese Werte spätere Änderungen an den entsprechenden CSS-Eigenschaften.
  • Ungültige Werte (z. B. negative duration, iterations: -1 oder ein unbekannter easing-String) führen bei updateTiming() zu einem TypeError.
  • Kompatibilität: getTiming(), getComputedTiming() und updateTiming() gibt es in Chrome/Edge 75+, Firefox 63+ und Safari 13.1+. Ältere Browser brauchen das Polyfill web-animations-js.