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, gdy są używane prawidłowo, poprawiają postrzeganie i zapamiętywanie marki przez użytkowników oraz pomagają im w działaniach i nawigacji w aplikacji, zapewniając 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ć całkiem znajome, jeśli korzystasz z reguł @keyframe
. Najpierw musisz utworzyć obiekt kluczowego klatki. Jak w CSS może 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;
}
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ść używania efektów w sekwencji i większą kontrolę nad stanem odtwarzania.
Powyżej 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 przenikania usuń kopię.
sterowanie 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ą funkcji animation.finished.then()
przed wykonaniem następnego zestawu animacji w łańcuchu. 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).
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 Web Animations API umożliwia odtwarzanie, wstrzymywanie i odwracanie animacji.
Korzystając z .reverse()
, możesz utworzyć płynną, odwróconą animację, która została pokazana w poprzedniej części prezentacji. 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 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 mysz się porusza, przeglądarka ponownie oblicza położenie każdej piłki na szlaku komety i tworzy animację w tym nowym punkcie. Przeglądarka wie teraz, czy usunąć stare animacje (włączać zastępowanie), gdy:
- Animacja została zakończona.
- W kolejności złożonej znajduje się co najmniej jedna animacja, która została już zakoń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 metod, które pozwolą Ci 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 bazowego oraz wszystkich animacji 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 ustawić tryb złożony animacji, co oznacza, że oprócz domyślnego trybu „zastąp” mogą się one sumować lub agregować. Tryby złożone pozwalają programistom tworzyć różne animacje i kontrolować sposób łą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)
. '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
. Pierwszym z nich jest makroanimacja, w którym menu jest przesuwane o pełną wysokość o pełną wysokość w celu wysuwania się z góry strony, a druga – mikroanimacja – powoduje małe odbicie ekranu w momencie dotknięcia ekranu. 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
Wszystkie te funkcje stanowią ekscytujące dodatki do animacji we współczesnych przeglądarkach, a wkrótce zostaną dodane kolejne. Aby dowiedzieć się więcej o nadchodzących zmianach, zapoznaj się z tymi specyfikacjami: