Eine neue Methode, um Keyframe-Animationen zu verzögern

Avatar of Eric Johnson
Eric Johnson am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Wenn Sie jemals eine Pause zwischen jeder Iteration Ihrer CSS-@keyframes-Animation hinzufügen wollten, waren Sie wahrscheinlich frustriert, als Sie feststellten, dass es dafür keine integrierte Methode in CSS gibt. Sicher, wir können den Start einer Reihe von @keyframes mit animation-delay verzögern, aber es gibt keine Möglichkeit, Zeit zwischen der ersten Iteration durch die Keyframes und jeder folgenden Ausführung hinzuzufügen.

Dies ergab sich, als ich diese Sternschnuppen-Animation als Hintergrund für das Homepage-Banner eines Weltraum-Themen-Mitarbeiterportals adaptieren wollte. Ich wollte weniger Sterne verwenden, um die Ablenkung vom Hauptinhalt zu reduzieren, die CPUs vor dem Schmelzen zu bewahren und die Sternschnuppen trotzdem zufällig erscheinen zu lassen.

Kein Pausieren

Zum Vergleich.

Die „originale“ Verzögerungsmethode

Hier ist ein Beispiel, bei dem ich die traditionelle Keyframe-Verzögerungstechnik auf meine Version der Sternschnuppen angewendet habe.

Dieser Ansatz beinhaltet, herauszufinden, wie lange die Verzögerung zwischen den Iterationen dauern soll, und dann die Keyframes auf einen Bruchteil von 100% zu komprimieren. Dann behalten wir den Endzustand der Animation bei, bis er 100 % erreicht, um die Pause zu realisieren.

@keyframes my-animation {
  /* Animation happens between 0% and 50% */
  0% {
    width: 0;
  }
  15% {
    width: 100px;
  }
  /* Animation is paused/delayed between 50% and 100% */
  50%, 100% {
    width: 0;
  }
}

Ich habe den Hauptnachteil dieses Ansatzes erfahren: Jeder Keyframe muss manuell angepasst werden, was leicht schmerzhaft und definitiv fehleranfällig ist. Es ist auch schwieriger zu verstehen, was die Animation tut, wenn man alle Keyframes mental wieder auf 100 % hochrechnen muss.

Neue Technik: Während der Verzögerung ausblenden

Eine weitere Technik besteht darin, einen neuen Satz von @keyframes zu erstellen, der dafür verantwortlich ist, die Animation während der Verzögerung auszublenden. Dann wenden Sie diese gleichzeitig mit der ursprünglichen Animation an.

.target-of-animation {
  animation: my-awesome-beboop 1s, pause-between-iterations 4s;
}

@keyframes my-awesome-beboop {
  ...
}

@keyframes pause-between-iterations {
  /* Other animation is visible for 25% of the time */
  0% {
    opacity: 1;
  }
  25% {
    opacity: 1;
  }
  /* Other animation is hidden for 75% of the time */
  25.1% {
    opacity: 0;	
  }
  100% {
    opacity: 0;
  }
}

Eine Einschränkung dieser Technik ist, dass die Pause zwischen den Animationen ein ganzzahliges Vielfaches der „pausierten“ Keyframes sein muss. Das liegt daran, dass Keyframes, die unendlich wiederholt werden, sofort erneut ausgeführt werden, auch wenn längere Keyframes auf dasselbe Element angewendet werden.

Interessanter Nebenschauplatz: Als ich diesen Artikel begann, dachte ich fälschlicherweise, dass eine Easing-Funktion bei 0 % angewendet wird und bei 100 % endet. Es stellt sich heraus, dass die Easing-Funktion auf jede CSS-Eigenschaft angewendet wird, beginnend mit dem ersten Keyframe, bei dem ein Wert definiert ist, und endend mit dem nächsten Keyframe, bei dem ein Wert definiert ist (z. B. eine Easing-Kurve würde von 25 % bis 75 % angewendet, wenn die Keyframes 25% { left: 0 } 75% { left: 50px} wären). Rückblickend macht das total Sinn, denn es wäre schwierig, Ihre Animation anzupassen, wenn sie ein Teil der gesamten Easing-Kurve wäre, aber mein Verstand ist leicht geblasen.

In den obigen my-awesome-beboop Keyframes wird my-awesome-beboop dreimal im Hintergrund während der pause-between-animations Keyframes ausgeführt, bevor es für den Benutzer sichtbar wird, was wie seine zweite Schleife aussieht (tatsächlich ist es das fünfte Mal, dass es ausgeführt wurde).

Hier ist ein Beispiel, das dies verwendet, um eine Verzögerung zwischen den Sternschnuppen hinzuzufügen

 

Kann Ihre Animation während der Verzögerung nicht ausblenden?

Wenn Sie Ihre Animation während der Verzögerung auf dem Bildschirm behalten müssen, gibt es neben dem Ausblenden noch eine weitere Option. Sie können immer noch einen zweiten Satz von @keyframes verwenden, aber eine CSS-Eigenschaft so animieren, dass sie die Bewegung der primären Animation ausgleicht oder aufhebt. Wenn Ihre Hauptanimation beispielsweise translateX verwendet, können Sie in Ihrem Set von Verzögerungs-@keyframes left oder margin-left animieren.

Hier sind ein paar Beispiele

Pause durch Ändern von transform-origin

Pause durch Ausgleich von transform: translateX durch Animation der left-Eigenschaft

Im Falle des Pausierens der translateX-Animation müssen Sie bei den @keyframes ausgefallener werden, wenn Sie die Animation für mehr als nur eine einzelne Iteration pausieren müssen.

/* pausing the animation for three iterations */
@keyframes slide-left-pause {
  25%, 50%, 75% {
    left: 0;
  }
  37.5%, 62.5%, 87.5% {
    left: -100px;
  }
  100% {
    left: 0;
  }
}

Es kann zu geringfügigem Ruckeln während der Pause kommen. Im obigen translateX-Beispiel gibt es ein leichtes Vibrieren des Balls während des slide-left-pause, da die Animationen um die Vorherrschaft kämpfen.

Zusammenfassung

Die beste Option in Bezug auf die Leistung ist, das Element während der Verzögerung auszublenden oder transform zu animieren. Das Animieren von Eigenschaften wie left, margin, width ist für einen Prozessor viel intensiver als das Animieren von opacity (obwohl die contain-Eigenschaft dies zu ändern scheint).

Wenn Sie Einblicke oder Kommentare zu dieser Idee haben, lassen Sie es mich wissen!


Vielen Dank an Yusuke Nakaya für die ursprüngliche Sternschnuppen-CSS-Animation, die ich auf CodePen geforkt habe.