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.
Poprawnie używane animacje poprawiają postrzeganie marki i pamięć o niej, pomagają użytkownikom w poruszaniu się po aplikacji i zapewniają kontekst w przestrzeni cyfrowej.
Interfejs Web Animations API to narzędzie, które umożliwia deweloperom tworzenie animacji imperatywnej za pomocą JavaScriptu. Został on 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ł on utworzony za pomocą element.animate()
czy reguł CSS (animacja lub przejście CSS). Oto przykład:
Najpierw "get"
klatek kluczowych przejścia, aby określić miejsce przejścia. Następnie utwórz 2 nowe animacje przezroczystości, aby włączyć efekt przejścia. Po zakończeniu przejścia między obrazami usuwasz kopię.
sterowanie animacjami za pomocą obietnic;
W Chromium 84 są teraz dostępne 2 metody, których można używać 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órz łańcuch animacji z uporządkowanymi plikami za pomocą funkcji 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)});
Połączyliśmy te animacje za pomocą parametru animation.finished.then()
przed wykonaniem następnej animacji w obrębie łańcucha. W ten sposób animacje będą pojawiać się w kolejności, a efekty będziesz stosować nawet do różnych elementów docelowych z różnymi ustawieniami (np. prędkości i łatwości).
Odtworzenie tego w kodzie CSS byłoby uciążliwe, zwłaszcza w przypadku stosowania unikalnych, ale uporządkowanych animacji do wielu elementów. Musisz użyć elementu @keyframe
, ustalić odpowiednie wartości procentowe czasu, by umieścić animacje, oraz użyć animation-delay
, zanim uruchomisz animacje w sekwencji.
Przykład: odtwarzanie, wstrzymywanie i odwracanie
To, co może się otworzyć, powinno się zamknąć. Na szczęście od Chromium 39 interfejs API Web Animations umożliwia odtwarzanie, wstrzymywanie i odwracanie animacji.
Możesz wziąć animację wyświetlaną wcześniej i zastosować ją jako płynną, odwróconą animację po ponownym kliknięciu przycisku za pomocą .reverse()
. Dzięki temu możesz stworzyć bardziej płynną i kontekstową interakcję z oknem modalnym.
Możesz utworzyć 2 animowane animacje (openModal
i przekształcenie przezroczystości w wierszu), a potem wstrzymać jedną z nich, opóźniając ją do czasu zakończenia drugiej. Możesz wtedy użyć obietnic, aby poczekać, aż wszystkie zostaną wykonane, zanim zaczniesz odtwarzać. 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 dotychczasowe są jeszcze uruchomione. 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, czy usunąć stare animacje (włączać zastępowanie), gdy:
- Animacja została zakończona.
- W układaniu złożonym znajduje się co najmniej 1 animacja, która jest również 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ć.
Oto kilka dodatkowych metod, które jeszcze bardziej zwiększą Twoją kontrolę nad 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 złożone pozwalają programistom tworzyć różne animacje i kontrolować sposób łączenia efektów. Obsługiwane są teraz 3 tryby złożone: 'replace'
(tryb 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 funkcji 'add'
funkcja wieloskładnikowa dodaje obrót i mnoży skalę, co daje końcowy stan rotate(720deg) scale(1.96)
. 'accumulate'
łączy przekształcenia, co daje w wyniku 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. Zapoznaj się z przyszłymi specyfikacjami, aby dowiedzieć się więcej o nadchodzących rozwiązaniach: