sterowanie animacjami za pomocą obietnic, poprawa wydajności dzięki wymiennym animacjom, płynniejsze animacje dzięki trybom kompozytowym i inne.
Data publikacji: 27 maja 2020 r.
Animacje użyte w prawidłowy sposób poprawiają postrzeganie i zapamiętywanie marki przez użytkowników, ukierunkowują ich działania oraz pomagają im w poruszaniu się po aplikacji – zapewniają kontekst w przestrzeni cyfrowej.
Interfejs Web Animations API to narzędzie, które umożliwia deweloperom tworzenie animacji imperatywnej za pomocą JavaScriptu. Został napisany, aby wspierać implementacje animacji i przejść CSS oraz umożliwić tworzenie nowych efektów, a także komponowanie i synchronizowanie efektów istniejących.
Chociaż Firefox i Safari wdrożyły już pełny zestaw funkcji ze specyfikacji, Chromium 84 wprowadza do Chrome i Edge wiele funkcji, które wcześniej nie były obsługiwane, umożliwiając współpracę między przeglądarkami.
Pierwsze kroki
Tworzenie animacji za pomocą interfejsu Web Animations API powinno być bardzo podobne do tworzenia reguł @keyframe
. Najpierw musisz utworzyć obiekt kluczowego klatki. W CSS może to wyglądać tak:
@keyframes openAnimation {
0% {
transform: scale(0);
}
100% {
transform: scale(1);
}
}
wyglądałby w JavaScriptzie tak:
const openAnimation = [
{ transform: 'scale(0)' },
{ transform: 'scale(1)' },
];
Gdzie ustawiasz parametry animacji w CSS:
.modal {
animation: openAnimation 1s 1 ease-in;
}
ustawiasz w JS:
document.querySelector('.modal').animate(
openAnimation, {
duration: 1000, // 1s
iterations: 1, // single iteration
easing: 'ease-in' // easing function
}
);
Ilość kodu jest mniej więcej taka sama, ale JavaScript daje Ci kilka supermocy, których nie ma sam CSS. Obejmuje to możliwość sekwencyjności efektów i większą kontrolę nad stanami odtwarzania.
element.animate()
Jednak po aktualizacji interfejs Web Animations API nie jest już ograniczony do animacji utworzonych za pomocą element.animate()
. Możemy też manipulować animacjami i przejęciami CSS.
getAnimations()
to metoda, która zwraca wszystkie animacje elementu niezależnie od tego, czy została utworzona za pomocą element.animate()
, czy za pomocą reguł CSS (animacja lub przejście CSS). Oto przykład:
Najpierw "get"
kluczowe klatki przejścia, aby określić, skąd pochodzi przejście. Następnie utwórz 2 nowe animacje przezroczystości, aby włączyć efekt przejścia. Po zakończeniu przejścia między obrazami możesz usunąć kopię.
Jak sterować animacjami za pomocą obietnic
W Chromium 84 masz teraz 2 metody, które można stosować z obietnicami: animation.ready
i animation.finished
.
animation.ready
pozwala na oczekiwanie na zastosowanie oczekujących zmian (czyli przełączanie się między metodami sterowania odtwarzaniem, takimi jak odtwarzanie i wstrzymywanie).animation.finished
umożliwia wykonywanie niestandardowego kodu JavaScript po zakończeniu animacji.
Wróćmy do naszego przykładu i utwórzmy sterowany łańcuch animacji za pomocą animation.finished
. Tutaj masz przekształcenie pionowe (scaleY
), a potem poziome (scaleX
) i zmianę krycia elementu potomnego:
const transformAnimation = modal.animate(openModal, openModalSettings);
transformAnimation.finished.then(() => { text.animate(fadeIn, fadeInSettings)});
Te animacje zostały połączone za pomocą elementu animation.finished.then()
przed wykonaniem następnego zestawu animacji w łańcuchu. W ten sposób animacje będą pojawiać się w porządku, a efekty będziesz stosować nawet do różnych elementów docelowych z różnymi ustawieniami (np. prędkości i łatwości).
W CSS trudno byłoby to odtworzyć, zwłaszcza w przypadku stosowania niepowtarzalnych, ale uporządkowanych animacji do wielu elementów. Musisz użyć @keyframe
, określić prawidłowe wartości procentowe czasu trwania animacji i użyć animation-delay
przed uruchomieniem animacji w sekwencji.
Przykład: odtwarzanie, wstrzymywanie i odtwarzanie wstecz
To, co może się otworzyć, powinno się zamknąć. Na szczęście od wersji Chromium 39 interfejs API animacji internetowych umożliwia odtwarzanie, wstrzymywanie i odwracanie animacji.
Możesz wziąć animację wyświetlaną wcześniej i zastosować do niej płynną, odwróconą animację, klikając ponownie przycisk .reverse()
. Dzięki temu możesz stworzyć bardziej płynną i kontekstową interakcję z oknem modalnym.
Możesz utworzyć 2 animowane elementy (openModal
i przekształcenie przejrzystości w ramce), a potem wstrzymać jedną z nich, opóźniając ją do czasu zakończenia drugiej. Następnie możesz użyć obietnic, aby poczekać, aż wszystkie zostaną ukończone. Na koniec możesz sprawdzić, czy flaga jest ustawiona, a następnie odwrócić każdą animację.
Przykład: interakcje dynamiczne z częściowymi klatkami kluczowymi
selector.animate([{transform: `translate(${x}px, ${y}px)`}],
{duration: 1000, fill: 'forwards'});
W tym przykładzie jest tylko 1 klatka kluczowa i nie ma określonej pozycji początkowej. Oto przykład użycia częściowych klatek kluczowych. Obsługa myszy wykonuje tutaj kilka czynności: ustawia nową lokalizację końcową i uruchamia nową animację. Nowa pozycja początkowa jest określana na podstawie bieżącej pozycji podstawowej.
Nowe przejścia mogą być uruchamiane, gdy istniejące są nadal aktywne. Oznacza to, że bieżące przejście zostaje przerwane i tworzy się nowe.
Poprawa wydajności dzięki zastępowaniu animacji
Podczas tworzenia animacji na podstawie zdarzeń, takich jak 'mousemove'
, za każdym razem tworzona jest nowa animacja, co może szybko zużywać pamięć i obniżać wydajność. Aby rozwiązać ten problem, w wersji Chromium 83 wprowadzono zastępowalne animacje, które umożliwiają automatyczne czyszczenie. Ukończone animacje są oznaczane jako zastępowalne i automatycznie usuwane, jeśli zostaną zastąpione przez inną ukończoną animację. Na przykład:
elem.addEventListener('mousemove', evt => {
rectangle.animate(
{ transform: translate(${evt.clientX}px, ${evt.clientY}px) },
{ duration: 500, fill: 'forwards' }
);
});
Za każdym razem, gdy przesuniesz kursor, przeglądarka ponownie oblicza położenie każdej kuli w śladzie komety i tworzy animację dla tego nowego punktu. Przeglądarka wie teraz, aby usuwać stare animacje (umożliwiając zastąpienie), gdy:
- Animacja została zakończona.
- W porządku mieszanym znajduje się co najmniej 1 animacja, która również jest ukończona.
- Nowe animacje mają te same właściwości.
Możesz sprawdzić, ile animacji zostało zastąpionych, zliczając licznik przy każdej usuniętej animacji i używając anim.onremove
, aby go uaktywnić.
Istnieje kilka dodatkowych właściwości i metod, które pozwalają jeszcze lepiej kontrolować animację:
animation.replaceState
umożliwia śledzenie, czy animacja jest aktywna, trwała czy usunięta.animation.commitStyles()
aktualizuje styl elementu na podstawie stylu podstawowego wraz ze wszystkimi animacjami elementu w kolejności złożonej.animation.persist()
oznacza, że animacji nie można zastąpić.
Gładsze animacje dzięki trybom złożonym
Dzięki interfejsowi Web Animations API możesz teraz ustawiać tryb złożony animacji, co oznacza, że mogą one być dodawane lub kumulowane, oprócz domyślnego trybu „zastępowania”. Tryby kompozytowania umożliwiają deweloperom tworzenie różnych animacji i kontrolowanie sposobu łączenia efektów. Obsługiwane są teraz 3 tryby kompozytowe: 'replace'
(domyślny), 'add'
i 'accumulate'
.
Gdy tworzysz animacje, deweloper może napisać krótkie, odrębne efekty i zobaczyć je połączone. W tym przykładzie do każdego pola stosujemy klatkę kluczową rotacji i skali, a jedyną zmianą jest tryb kompozytowy dodany jako opcja:
W domyślnym trybie składania 'replace'
końcowa animacja zastępuje właściwość transform i kończy się w punkcie rotate(360deg) scale(1.4)
. W przypadku 'add'
kompozycja dodaje obrót i mnoży skalę, co daje w efekcie końcowy stan rotate(720deg) scale(1.96)
. Funkcja 'accumulate'
łączy przekształcenia, co daje w wyniku funkcję rotate(720deg) scale(1.8)
. Więcej informacji o szczegółach tych trybów złożonych znajdziesz w specyfikacji animacji internetowych w sekcji Enumeracje CompositeOperation i CompositeOperationOrAuto.
Zapoznaj się z tym przykładem elementu interfejsu użytkownika:
Tutaj skomponowano 2 animacje top
. Pierwsza to makroanimacja, która przesuwa menu w dół o całą wysokość menu jako efekt przesuwania od góry strony. Druga to mikroanimacja, która powoduje lekkie odbicie, gdy menu dociera do dołu. Korzystanie z trybu złożonego 'add'
umożliwia płynniejsze przejście.
const dropDown = menu.animate(
[
{ top: `${-menuHeight}px`, easing: 'ease-in' },
{ top: 0 }
], { duration: 300, fill: 'forwards' });
dropDown.finished.then(() => {
const bounce = menu.animate(
[
{ top: '0px', easing: 'ease-in' },
{ top: '10px', easing: 'ease-out' },
{ ... }
], { duration: 300, composite: 'add' });
});
Co dalej z interfejsem Web Animations API
To ekscytujące dodatki do możliwości animacji w dzisiejszych przeglądarkach. Jeszcze więcej funkcji jest w trakcie tworzenia. Aby dowiedzieć się więcej o nadchodzących zmianach, zapoznaj się z tymi specyfikacjami: