Sytuacja kobiet w IT w 2024 roku
17.09.20217 min
Mikael Ainalem

Mikael AinalemCTONorban

Jak stworzyć animację z CSS clip-path

Sprawdź, jak zmieniającą kształt animację przy pomocy CSS clip-path na podstawie przykładu z przyciskiem play oraz pause.

Jak stworzyć animację z CSS clip-path

Ostatnio zainteresowałem się tematem morfingu. Jak zwykle, kiedy znajduję rzeczy, w które mogę się bardziej zagłębić, wystarczy mi energii na zrobienie paru demek na moim profilu na Codepen. Codepen to idealne miejsce dla wyrażania własnej kreatywności. To społeczność pełna nowych pomysłów i super ludzi. W Codepen najważniejsze jest dzielenie się swoją pracą. Większość stara się tam doskonalić oraz rozwijać razem z innymi.

Artykuł ten dotyczy tego, co nazywam, z braku lepszego terminu, morfingiem clip-path. Omówimy tutaj pen na moim koncie Codepen o nazwie Play Pause Button oraz technikę, która za nim stoi. Oto krótki film z animacją, którą się zajmiemy.

Czym jest morfing?

Morfing to technika polegająca na przekształcaniu jednego obrazu w inny. To animacja zmieniająca kształt, w której dwuwymiarowy obiekt, na przykład obraz, figura itp., przybiera inny kształt.

Technicznie jest to interpolacja z jednego zestawu współrzędnych do drugiego. Dla uproszczenia artykuł ten traktuje kształt początkowy i stan końcowy jako zbiory tej samej liczby węzłów. Teoretycznie możliwe jest stworzenie efektu przy różnej liczbie węzłów.

Posiadanie takiej samej liczby węzłów w punkcie początkowym lub kształcie, jak na ostatecznym rysunku, bardzo upraszcza sprawę. Efekt nie staje się też przez to mniej fajny.

Tutaj mamy przykład podstawowej animacji morfingu clip-path. Film pokazuje kształt przechodzący na przemian między pudełkiem a gwiazdą. Efektem jest zbiorowy ruch wszystkich węzłów jednocześnie. Niektóre z nich poruszają się na duże odległości, a inne wcale.

Cecha ta jest charakterystyczna dla morfingu — odróżnia go od innych rodzajów animacji.

Morfing w SVG

Większość efektów morfingu, które można obecnie zobaczyć w internecie, prezentowana jest w formacie SVG. Grafika wektorowa dotyczy współrzędnych, a więc SVG jest naturalnym punktem wyjścia do tworzenia efektów morfingu i przy tym całkiem wyrafinowanym narzędziem.

Narzędzia te pomagają umieszczać obiekty na różnych warstwach, tworzyć różne kolory, przestawiać obiekty i rozmiary itp. Szczególnie interesująca jest edycja kształtów, w której można manipulować oddzielnymi węzłami i zmieniać figury.

Dwa kroki w tworzeniu efektu zmiany kształtu

Tworzenie animacji zmiany kształtu można z grubsza podzielić na dwie czynności:

  • Modelowanie
  • Animacja


Modelowanie odnosi się do zmiany kształtu poprzez przesunięcie punktów wektorami. Prawie zawsze zaczynam od tworzenia kształtów w Inkscape, czyli edytorze grafiki wektorowej. To samo dotyczy wersji demo omówionej w tym artykule. Zasadniczo jest to obiekt SVG, który częściowo przeportowałem do CSS.

Modelowanie przycisku play/pause

Animacja w moim demo składa się z dwóch oddzielnych kształtów. Właściwie to patrzymy na animację między symbolem play a symbolem pause.

Symbol odtwarzania ma postać trójkąta z zaokrąglonymi rogami. Symbol pauzy jest zupełnie inny; składa się z dwóch równoległych prętów. Ponieważ dwie części mają inną liczbę kształtów (1 vs. 2), musimy je jakoś połączyć, żeby uzyskać dobry efekt.

Najłatwiej jest podzielić symbol odtwarzania na dwie równe części. Wreszcie, dokładamy niewielką rotację, aby uwzględnić różnicę w kącie i położeniu. Poniżej znajduje się obraz tego, jak wygląda model połowy symbolu play w edytorze wektorów.


Połowa symbolu odtwarzania


Przybliżmy to trochę i przyjrzyjmy się kompozycji kształtu. Każda połowa składa się z 64 węzłów. Zwróć uwagę na dużą liczbę węzłów po lewej stronie.

Nierówne rozmieszczenie węzłów w tym miejscu jest celowe. Są one bardziej skoncentrowane po lewej stronie, a ich umiejscowienie wzmacnia efekt. Dolny róg pozornie się przesunie, gdy trójkąt zmieni swój kształt. Wtedy trzy rogi zmieniają się w cztery.


Powiększony widok węzłów w połowie symbolu odtwarzania


Przyjrzyjmy się, jak model ten wygląda w kodzie:

// Play/pause model
<svg ...>
  <circle ... /> /* red circle */
  <path d="..." /> /* Half play symbol */
  <path d="..." /> /* Half play symbol */
  <path d="..." /> /* Pause bar, left */
  <path d="..." /> /* Pause bar, right */
</svg>

Wprawiamy rzeczy w ruch

Animacja oznacza następnie faktyczną zmianę początkowego kształtu do ostatecznej figury. Tworzenie ruchu SVG jest na razie procesem manualnym. Należy tutaj ręcznie interpolować wszystkie oddzielne współrzędne.

Jednym ze sposobów na osiągnięcie tego jest, na przykład, w JavaScript, użycie wywołania API requestAnimationFrame. Dzięki funkcji wywołania zwrotnego można obliczyć wartości dla każdej ramki. Jednak tworzenie animacji w ten sposób jest uciążliwe i wymaga poświęcenia czasu na skonfigurowanie.

Inną opcją jest użycie frameworku do animacji. To ułatwia sprawę i sprawia, że nie trzeba budować animacji od podstaw. Tak czy inaczej, nadal będziesz musiał napisać kod, aby skonfigurować i zainicjować animację. Krótko mówiąc, potrzebny jest dodatkowy wysiłek.

Na czym polega morfing clip-path?

Morfing clip-path CSS jest bardzo podobny do morfingu w SVG. Jest jednak jedna ciekawa różnica: wykonanie odbywa się w dziedzinie CSS, a nie SVG.

Przejście na CSS umożliwia wykorzystanie inteligentnego silnika do transformacji CSS. Wykonuje on praktycznie wszystkie ciężkie prace. Tworzy poszczególne kroki animacji i, co jest również ważne, robi to natywnie. Natywne animacje są przyspieszane sprzętowo i wydajne.

Kolejną rzeczą, którą dostajemy za darmo, jest pełna interpolacja zestawu współrzędnych. Silnik obsłuży osobno transformacje dla każdego z koordynatów. Jedyne, co musimy zrobić, to podać przeglądarce początkowy kształt i stan końcowy. W kodzie potrzebujemy jednej linii, aby uruchomić animację. Oto przykład:

.animated {
  transition: clip-path 500ms;
}


A teraz, jeśli chcemy, możemy dodać stany początkowe i końcowe. Najłatwiej to zrobić, używając nowego stanu, czyli klasy CSS. Na potrzeby tego przykładu użyjmy stanu aktywnego, który jest tym samym stanem, jak ten użyty w demo.

.animated {
  transition: clip-path 500ms;
  clip-path: polygon(...); // start state
}
.active .animated {
  clip-path: polygon(...); // end state
}


Po utworzeniu animacji potrzebujemy tylko wyzwalacza, aby ją rozpocząć. Może on zasadniczo być zdarzeniem, takim jak np. licznik czasu, dotknięcie lub najechanie myszą. Prostym sposobem na aktywację animacji jest dodanie obsługi zdarzenia click.

<div class="animated" onclick="this.classList.toggle('active')">
  ...
</div>


Przeglądarka może oprócz transformacji również zastosować wygładzanie przejść w animacji. Złagodzenie jest wisienką na torcie, dzięki której ruch wygląda o wiele płynniej i bardziej realistycznie. 

Narzędzia developerskie

Jakby komuś jeszcze było mało, istnieje również duża korzyść ze stosowania clip-path w narzędziach deweloperskich. Można je podejrzeć i modyfikować w CSS.

Mając narzędzia deweloperskie, możesz testować animacje, bezpośrednio je edytując. Inspektor jeszcze bardziej ułatwia iterację i korzystanie z różnych kształtów.

Tutaj znajduje się film, który pokazuje, jak łatwo jest wypróbować różne animacje morfingu w CSS.


Oto dwa inne mocne argumenty przemawiające za pracą z wektorami w CSS

  • Edytor ścieżek Firefoksa umożliwia manipulowanie clip-path z poziomu inspektora
  • Narzędzia deweloperskie obsługują nagrywanie animacji, co jest idealne dla dopracowywania animacji.

Przechodzenie na CSS

Pomysł polega tutaj na utworzeniu zastępczego znacznika, który daje takie same wizualne dane wyjściowe, jak oryginalny znacznik. Poniżej znajduje się ilustracja w pseudokodzie, jak coś takiego mogłoby wyglądać.

/* From SVG */
<svg ...>
  <path d="..." />
</svg>
/* To CSS */
<div style="clip-path: polygon(...)"></div>


W clip-path obsługiwane jest wiele różnych metod. Najbardziej odpowiednią metodą, ze względu na podobieństwa w formacie, jest wielokąt. Wielokąty istnieją w SVG, ale ich użycie jest jednak rzadkie.

Edytor wektorów, którego używam, czyli Inkscape, pracuje ze ścieżkami i zwykle zapisuje dane wyjściowe jako ścieżki. Dlatego potrzebujemy sposobu, aby przejść od ścieżek do wielokątów, lub bardziej szczegółowo, przekonwertować deskryptor ścieżki (d) na wielokąt clip-path.

Istnieją podobieństwa między tymi dwoma formatami. Jeśli ścieżka SVG jest całkowicie pozbawiona krzywych, to oba formaty są bardzo podobne. Różnica polega więc głównie na niewielkiej zmianie składni. Mam w zwyczaju tworzenie modeli morfingu bez żadnych krzywych, czyli z liniami prostymi zapisanymi we współrzędnych absolutnych.

W ten sposób, z ograniczeniami w formacie, konwersja będzie wymagała znacznie mniej. Gdy wszystko jest już odpowiednio przygotowane, do właściwej konwersji używam skryptu Node.js. Poniżej znajduje się konwersja gwiazdy.


Gwiazda do przekonwertowania z SVG do CSS


Kod:

<path d="M 73.924957,90 49.42372,75.971326 24.48224,89.124336 29.669821,60.42209 10,39.681618 37.707342,35.971327 50.492205,10 62.4287,36.409157 90,41.098468 69.669822,61.130517 Z" />
/* Converts to */
<div style="clip-path: polygon(73.92496% 90%, 49.42372% 75.97133%, 24.48224% 89.12434%, 29.66982% 60.42209%, 10% 39.68162%, 37.70734% 35.97133%, 50.4922% 10%, 62.4287% 36.40916%, 90% 41.09847%, 69.66982% 61.13052%);"></div>


Tutaj znajduje się kolejny sposób wykonywania konwersji za pomocą krzywych.

Przyszłość

Aktualizacja, która zmieni dość dużo, jest już blisko. Chodzi o clip-path: path(). Funkcja ta jest następną generacją konwersji z SVG do CSS.

Gdy przeglądarki w pełni obsługują clip-path: path(), to przejście z SVG do CSS będzie bardzo proste. W istocie oba będą interoperacyjne. Poniżej przedstawiamy, jak obecnie wygląda rzeczywiste wsparcie. W chwili pisania tego tekstu tylko Firefox obsługiwał tę regułę.

Źródła

Demo przycisków Play i Pause jest na Codepen

TLDR;

  • Użyj SVG, aby utworzyć kształty początkowe i końcowe
  • Przekonwertuj ścieżki SVG na wielokąty clip-path CSS
  • Użyj narzędzi deweloperskich do dostrojenia efektu morfingu
  • Wygładzaj i synchronizuj animację, aby ją udoskonalić
  • No i proszę, w taki sposób stworzyliśmy wspaniały efekt zmiany kształtu
  • Clip-path: path() będzie świetne.


Oryginał tekstu w języku angielskim możesz przeczytać tutaj.

<p>Loading...</p>