Tarcze Apple Watch

Po ogłoszeniu nowego zegarka firmy Apple w tym tygodniu, postanowiłem stworzyć tarcze aktywności za pomocą CSS.

W tym artykule wykorzystamy animacje klatek kluczowych CSS i sztuczki z overflow, aby stworzyć radialne paski postępu znajdujące się w sekcji aktywności nowego zegarka od Apple.

Demo

Oto przykład końcowego efektu.

Activity 10:09

Radialne paski postępu

Wyświetlacz aktywności zegarka składa się z 3 tarcz. Każdy jest czymś w rodzaju paska postępu w kształcie łuku wokół okręgu. Stworzenie tego kształtu jest trochę skomplikowane, ale możemy to zrobić wykorzystując dwa kliny i starannie dopasowaną animację.

Rozpoczniemy od prostego kształtu półkola.

Tak wygląda kod HTML dla tego kształtu:

<div class="dial-container">
  <div class="wedge"></div>
</div>

Nadajemy klinowi kształt półkola korzystając z właściwości border-radius i obracamy go używając keyframe.

.wedge {
  animation: rotate 4s infinite linear;
  border-radius: 0 4em 4em 0;
  background: red;
  width: 2em;
  height: 4em;
  transform-origin: 0% 50%;
}

@keyframes rotate {
  100% {
    transform: rotateZ(360deg);
  }
}

Maskowanie

We wcześniejszych eksperymentach, próbowałem stworzenie tego efektu za pomocą właściwość clip w CSS. Działało w niektórych przeglądarkach, ale to przestarzała i skomplikowana właściwość. W zamian możemy stworzyć podobny efekt korzystając z overflow:hidden na kontenerze.

W grę wchodzą dwa elementy. dial-container jest dwa razy krótszy niż wedge i posiada właściwość overflow ustawioną na hidden. Umieszczając go poza kontenerem, możemy obrócić go w polu widzenia.

.dial-container {
  position: absolute;
  top: 0;
  left: 2em;
  width: 2em;
  height: 4em;
  overflow: hidden;
}

Kontener jest umieszczony po prawej stronie klina, a klin jest następnie obrócony w polu widzenia.

Aby stworzyć pełne koło, musimy stworzyć drugi klin. Możemy to zrobić tworząc drugi kontener umieszczony po lewej stronie i obracając klin z prawej.

Możemy teraz to połączyć i stworzyć okrągłą tarczę. Dodamy również animację, aby druga połowa tarczy zaczęła się poruszać po pierwszej.

Pełne koło

Oto kod HTML dla tych dwóch części. Dodałem osłonę, aby można było umieścić oba kontenery na wierzchu każdej części

<div class="wrapper">
  <div class="dial-container container1">
    <div class="wedge"></div>
  </div>
  <div class="dial-container container2">
    <div class="wedge"></div>
  </div>
</div>

I CSS, aby obsługiwała osłonę, kontenery i dwa kliny.

.wrapper {
  position: absolute;
  width: 4em;
  height: 4em;
  left: calc(50% - 2em);
}
.dial-container {
  position: absolute;
  top: 0;
  bottom: 0;
  overflow: hidden;
  width: 2em;
}
.wedge {
  background: red;
  height: 4em;
  width: 2em;
}
.container1 {
  left: 2em;
}
.container1 .wedge {
  animation: rotate-bg-1 4s infinite linear;
  border-radius: 0 4em 4em 0;
  left: 0;
  transform-origin: 0 50%;
}
.container2 {
  left: 0;
}
.container2 .wedge {
  animation: rotate-bg-2 4s infinite linear;
  border-radius: 4em 0 0 4em;
  transform-origin: 2em 2em;
}
/* First animation moves 180 degrees in the first 2 seconds */
@keyframes rotate-bg-1 {
  50%, 100% {
    transform: rotateZ(180deg);
  }
}
/* Second animation moves 180 degrees in the last 2 seconds */
@keyframes rotate-bg-2 {
  0%, 50% {
    transform: rotateZ(0);
  }
  100% {
    transform: rotateZ(180deg);
  }
}

Rezultat powinien wyglądać tak:

Postęp

Kolejnym krokiem jest zmienienie klina w pasek. Możemy to wykonać maskując środek. Dodanie okrągłego pseudo-elementu do kontenera i ustawienie koloru tła daje pożądany efekt.

<div class="wrapper">
  <div class="dial-container container1">
    <div class="wedge"></div>
  </div>
  <div class="dial-container container2">
    <div class="wedge"></div>
  </div>
</div>

.wrapper::after {
  content: "";
  background: #fff;
  border-radius: 50%;
  width: 3em;
  height: 3em;
  position: absolute;
  top: 0.5em;
  left: 0.5em;
}

Otrzymaliśmy coś wyglądające bardziej jak radialne paski postępu aktywności od Apple.

Zaokrąglanie krawędzi

Prezentacja Apple Watch pokazuje ładnie zaokrąglone końce pasków postępu. Aby to odtworzyć, dodamy i zaanimujemy kilka elementów na każdym końcu paska. Aby rozpocząć, dodamy dodatkowe elementy.

<div class="wrapper">
  <div class="dial-container container1">
    <div class="wedge"></div>
  </div>
  <div class="dial-container container2">
    <div class="wedge"></div>
  </div>
  <div class="marker start"></div>
  <div class="marker end"></div>
</div>

Znacznik start pozostanie na początku, a znacznik end musi być zaanimowany, aby podążać za paskiem postępu. Możemy poradzić sobie z tym za pomocą CSS.

.marker {
  background: green;
  border-radius: 50%;
  height: 0.5em;
  width: 0.5em;
  position: absolute;
  top: 0;
  left: calc(50% - 0.25em);
}
.end {
  animation: rotate-marker 4s infinite linear;
  transform-origin: 50% 2em;
}
@keyframes rotate-marker {
  100% {
    transform: rotateZ(360deg);
  }
}

CSS ustawia dwa znaczniki jako zielone koła i umieszcza je w górnej środkowej części ekranu. Następnie znacznik end uzyskuje animację rotate-marker i transformację transform-origin na środku kontenera. To oznacza, że podczas obracania znaczniki będą poruszały się po łuku.

Zmiana koloru znaczników na czerwony pozwala na wkomponowanie ich w pasek i nadanie efektu zaokrąglenia. Wzbogacenie animacji o cubic-bezier dodaje również trochę charakteru.

Składając wszystko razem

Te trzy radialne paski postępu razem tworzą tarcze aktywności Apple Watch. Jeśli chcesz zobaczyć cały kod, pełne demo jest dostępne na Codepen.

Activity 10:09 </header>
</div> </article></section>