Recreating the Apple Watch Breathe App Animation

Avatar of Geoff Graham
Geoff Graham am

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

Die Apple Watch verfügt über eine Standard-App namens „Atmen“, die Sie daran erinnert, nun ja, zu atmen. Eigentlich steckt mehr dahinter, aber der Gedanke, an das Atmen erinnert werden zu müssen, bringt mich zum Kichern. Wichtig ist, dass die App diese ziemlich geniale Benutzeroberfläche mit einer schönen Animation hat.

Foto mit freundlicher Genehmigung von Apple Support

Ich dachte, es wäre lustig, das Design in reinem CSS nachzubilden. Hier ist, wie weit ich gekommen bin, was ziemlich nah dran zu sein scheint.

Siehe den Pen Apple Watch Breathe App Animation von Geoff Graham (@geoffgraham) auf CodePen.

Die Kreise erstellen

Zuerst brauchen wir eine Reihe von Kreisen, die dieses blumenähnliche Design bilden. Die App selbst fügt dem Layout für jede Minute, die dem Timer hinzugefügt wird, einen Kreis hinzu, aber wir werden uns für diese Demo an eine statische Menge von sechs halten. Es scheint, als könnten wir trickreich werden, indem wir ::before und ::after verwenden, um die HTML-Markierung zu reduzieren, aber wir können es einfach halten.

<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>

Wir werden die volle Größe jedes Kreises auf 125px setzen, was eine willkürliche Zahl ist. Wichtig ist, dass der Standardzustand der Kreise darin besteht, dass sie alle übereinander gestapelt sind. Wir können absolute Positionierung verwenden, um das zu erreichen.

.circle {
  border-radius: 50%;
  height: 125px;
  position: absolute;
  transform: translate(0, 0);
  width: 125px;
}

Beachten Sie, dass wir die Funktion translate der transform-Eigenschaft verwenden, um alles zu zentrieren. Ursprünglich hatte ich versucht, grundlegende top, right, bottom, left-Eigenschaften zu verwenden, fand aber später heraus, dass das Animieren von translate viel flüssiger ist. Ich hatte auch ursprünglich gedacht, dass die Positionierung der Kreise im vollständig ausgefahrenen Zustand der beste Ausgangspunkt wäre, fand aber auch, dass die Animationen auf diese Weise umständlich zu erstellen waren, da jede zurückgesetzt werden musste, um sie zu zentrieren. Lektionen gelernt!

Wenn wir hier aufhören würden, wäre nichts auf dem Bildschirm, und das liegt daran, dass wir keine background-Farbe festgelegt haben. Die schönen, schicken Farben der App werden wir gleich behandeln, aber es könnte hilfreich sein, vorerst einen weißen Hintergrund mit einem Hauch von Opazität hinzuzufügen, um zu sehen, was passiert, während wir arbeiten.

Siehe den Pen Apple Watch Breathe App – Schritt 1 von Geoff Graham (@geoffgraham) auf CodePen.

Wir brauchen einen Container!

Sie haben vielleicht bemerkt, dass unsere Kreise schön gestapelt sind, aber weit vom eigentlichen Mittelpunkt des Viewports entfernt. Wir müssen diese Kerle in ein Elternelement einpacken, das wir verwenden können, um die gesamte Gruppe zu positionieren. Außerdem dient dieser Container später als Element, das die gesamte Gruppe pulsiert und dreht. Das war eine weitere Lektion, die ich auf die harte Tour lernen musste, weil ich stur die zusätzliche Markierung eines Containers nicht wollte und dachte, ich könnte sie umgehen.

Wir nennen den Container hier .watch-face und setzen ihn auf die gleiche Breite und Höhe wie ein einzelner Kreis.

<div class="watch-face">
  <div class="circle"></div>
  <div class="circle"></div>
  <div class="circle"></div>
  <div class="circle"></div>
  <div class="circle"></div>
  <div class="circle"></div>
</div>

Jetzt können wir dem Body-Element ein wenig flex hinzufügen, um alles zu zentrieren.

body {
  background: #000;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100vh;
}

Siehe den Pen Apple Watch Breathe App – Schritt 2 von Geoff Graham (@geoffgraham) auf CodePen.

Als nächstes, die Kreise animieren

Zu diesem Zeitpunkt war ich gespannt darauf, die Kreise in dieser schönen floralen, überlappenden Anordnung zu sehen. Ich wusste, dass es schwierig sein würde, die genaue Position jedes Kreises zu animieren, ohne sie zuerst positioniert zu sehen. Also habe ich die transform-Eigenschaft jedes Kreises überschrieben, um zu sehen, wo sie landen würden.

Wir könnten für jeden Kreis eine Klasse einrichten, aber die Verwendung von :nth-child scheint einfacher zu sein.

.circle:nth-child(1) {
  transform: translate(-35px, -50px);
}

/* Skipping 2-5 for brevity... */

.circle:nth-child(6) {
  transform: translate(35px, 50px);
}

Es brauchte ein paar Versuche und Irrtümer, um Koordinaten zu finden, die funktionierten. Es hängt letztendlich von der Größe der Kreise ab und erfordert möglicherweise etwas Feingefühl.

Siehe den Pen Apple Watch Breathe App – Schritt 3 von Geoff Graham (@geoffgraham) auf CodePen.

Mit den Koordinaten können wir die Animationen registrieren. Ich habe die transform-Koordinaten entfernt, die auf jedes :nth-child angewendet wurden, und sie in Keyframes verschoben

@keyframes circle-1 {
  0% {
    transform: translate(0, 0);
  }
  100% {
    transform: translate(-35px, -50px);
  }
}

/* And so on... */

Ich muss zugeben, dass die Art und Weise, wie ich es gemacht habe, sich sehr ungeschickt anfühlt, weil jeder Kreis seine eigene Animation hat. Es wäre geschickter, eine Animation zu haben, die sie alle steuern kann, um die Kreise zu verschieben und neu zu zentrieren, aber vielleicht hat jemand anderes, der das liest, eine Idee und kann sie in den Kommentaren teilen.

Jetzt können wir diese Animationen anstelle von transform auf jedes :nth-child anwenden

.circle:nth-child(1) {
  animation: circle-1 4s ease alternate infinite;
}

/* And so on... */

Beachten Sie, dass wir animation-timing-function auf ease gesetzt haben, weil sich das gut anfühlt ... zumindest für mich! Wir haben auch animation-direction auf alternate gesetzt, damit es vorwärts und rückwärts spielt, und animation-iteration-count auf infinite, damit es weiterläuft.

Siehe den Pen Apple Watch Breathe App – Schritt 4 von Geoff Graham (@geoffgraham) auf CodePen.

Farbe, Farbe, Farbe!

Oh ja, lass es uns malen! Soweit ich das beurteilen kann, gibt es im Design wirklich nur zwei Farben, und die Opazität erzeugt das Gefühl eines Spektrums.

Die Kreise links sind grünlich und die rechts sind irgendwie blau. Wir können die ungeradzahligen Kreise für das Grün und die geradzahligen für das Blau auswählen.

.circle:nth-child(odd) {
  background: #61bea2;
}

.circle:nth-child(even) {
  background: #529ca0;
}

Oh, und vergiss nicht, den weißen Hintergrund aus dem .circle-Element zu entfernen. Das schadet nichts, aber es ist schön, nach uns aufzuräumen. Ich habe das zugegebenermaßen beim ersten Mal vergessen.

Siehe den Pen Apple Watch Breathe App – Schritt 5 von Geoff Graham (@geoffgraham) auf CodePen.

Zu diesem Zeitpunkt haben andere Kommentatoren vorgeschlagen, dass der Ersatz von opacity durch mix-blend-mode mit dem Wert screen eine schönere Art ist, die Farben der Kreise zu mischen. Ich habe die Demos und den Code inzwischen aktualisiert.

Pulsieren und Drehen

Erinnern Sie sich an den lästigen .watch-face-Container, den wir erstellt haben? Nun, wir können ihn animieren, um die Kreise ein- und auszublenden, während wir die gesamte Gruppe drehen.

Ich hatte total vergessen, dass transform-Funktionen verkettet werden können. Das macht die Sache etwas sauberer, da wir scale() und rotate() in derselben Zeile anwenden können.

@keyframes pulse {
  0% {
    transform: scale(.15) rotate(180deg);
  }
  100% {
    transform: scale(1);
  }
}

...und das auf das .watch-face-Element anwenden.

.watch-face {
  height: 125px;
  width: 125px;
  animation: pulse 4s cubic-bezier(0.5, 0, 0.5, 1) alternate infinite;
}

Wie die Kreise möchten wir, dass die Animation beide Richtungen durchläuft und unendlich wiederholt wird. In diesem Fall fällt die Skalierung auf eine sehr kleine Größe, während sich die Kreise übereinander stapeln, und das Ganze dreht sich auf dem Weg nach außen zur Hälfte, bevor es auf dem Weg nach innen zurückkehrt.

Ich gebe zu, dass ich kein Experte darin bin, die richtige animation-timing-function für die flüssigsten oder exaktesten Animationen zu finden. Ich habe mit cubic-bezier herumgespielt und etwas gefunden, das sich meiner Meinung nach ziemlich gut anfühlt, aber es ist möglich, dass ein Standardwert wie ease-in genauso gut funktionieren würde.

Alles zusammen jetzt!

Hier ist alles in derselben Demo zusammengefasst.

Siehe den Pen Apple Watch Breathe App Animation von Geoff Graham (@geoffgraham) auf CodePen.

Nun denken Sie einfach daran zu atmen und lassen Sie uns alle einen friedlichen Tag haben. ☮️