Animacja w przykładach js z kodem. Tworzenie animacji w JavaScript

Wraz z pojawieniem się animacji CSS3, dokumenty HTML stały się znacznie atrakcyjniejsze i łatwiejsze do opracowania. Korzystając z reguły @keyframes, możesz łatwo zdefiniować różne parametry, w tym położenie i rozmiar elementu HTML. Parametr animacji odpowiada z kolei za uruchamianie i przesuwanie klatek kluczowych w zależności od określonych parametrów. Bez konieczności używania JavaScript i wtyczek, możemy łatwo stworzyć nawet najbardziej skomplikowane animacje, które będą działać bardzo płynnie we wszystkich nowoczesnych przeglądarkach.

Problemy pojawiają się, gdy do tworzenia animacji CSS3 trzeba używać JavaScript. Wszyscy wiemy, że JavaScript w większości przypadków jest pierwszą koniecznością, która pozwala nam obliczyć poszczególne wartości lub cały proces animacji.

Łączenie CSS i JavaScript przy użyciu nowej metody animate().

Nowa metoda javascript animate() pozwala nam kontrolować animacje za pomocą skryptu. Oczywiście nadal musimy użyć całej gamy parametrów CSS, aby zdefiniować nasze klatki kluczowe.


(wysokość: „0”),
(wysokość: „100%”)
], {
czas trwania: 3000,
iteracja: 2,
opóźnienie: 1000
});
W powyższym przykładzie do elementu dołączamy metodę animate(). W nawiasach kwadratowych definiujemy tyle stanów danego parametru, ile potrzebujemy, a w naszym przykładzie będziemy pracować na wysokości. Każda wartość jest zapisywana jako litera obiektu, a wartości są używane tylko dla jednego indywidualnego parametru. Kombinacje takie jak szerokość i wysokość są niedozwolone. Należy pamiętać, że same wartości muszą być cytowane i sformatowane w składni zgodnej z JavaScript, co oznacza użycie „backgroundColor” zamiast „background-color”. W kolejnej literze obiektu zaraz po zamknięciu nawiasów kwadratowych definiujemy dalszą animację. Chcemy zmieniać długość animacji za pomocą czasu trwania, częstotliwość powtórzeń za pomocą iteracji, a opcjonalnie możemy zdefiniować opóźnienie za pomocą parametru opóźnienia - parametr ten określa moment, w którym animacja powinna się rozpocząć. Wszystkie wartości czasu podawane są w milisekundach.

Zarządzamy zestawem klatek kluczowych i czasem ich trwania

Musimy uruchomić metodę animate() oddzielnie od każdego parametru, który chcemy zmienić. Oznacza to, że jeśli chcemy zmienić zarówno wysokość, jak i szerokość, będziemy musieli ponownie uruchomić animate().

Dokument.getElementById("element").animate([
(szerokość: „0”, przesunięcie: 0),
(szerokość: „10%”, przesunięcie, 1/3),
(szerokość: „100%”, przesunięcie: 1)
], {
czas trwania: 3000,
iteracja: 2,
opóźnienie: 1000
});
W powyższym przykładzie zmieniamy szerokość elementu. Szerokość powinna się zmieniać, zaczynając od 0, aż do 10 procent, a kończąc, gdy osiągnie 100 procent. Wszystko to będzie oczywiście towarzyszyć płynnej animacji. Dodatkowy parametr przesunięcia określa, że ​​zmiany od 0 do 10 procent zajmą 1/3 całkowitego czasu animacji, a przejście z 10 do 100 zajmie 2/3 całkowitego czasu animacji. Jednocześnie całkowity czas trwania animacji zależy od parametru czasu trwania. W tym przypadku pierwsza część odbędzie się w ciągu jednej sekundy, a druga w ciągu 2.

Zamiast definiować wartość w postaci ułamków zwykłych, możesz także użyć ułamków dziesiętnych. Musisz użyć liczb od 0 do 1. Na przykład zamiast 1/3 możesz użyć 0,33.

Więcej opcji animacji

Jeśli znasz parametr animacji CSS3, prawdopodobnie wiesz, że metoda animate() pozwala kontrolować proces animacji. Możesz zmienić kierunek, a także prędkość animacji i jej przyspieszenie. Jeśli chcesz określić, że po zakończeniu animacja powinna powrócić do początku, możesz to zrobić.

Dokument.getElementById("element").animate([

], {
czas trwania: 3000,
iteracja: 2,
opóźnienie: 1000,
kierunek: „wstecz”,
złagodzenie: „ułatwienie”,
wypełnienie: „do przodu”
});
Wartość kierunku zawiera informację o kierunku animacji. Jeśli ustawisz opcję odwrotną, animacja będzie odtwarzana w odwrotnej kolejności. Wartość alternatywna umożliwi odtworzenie animacji w standardowym kierunku, a następnie w kierunku przeciwnym. Wartość alternatywno-odwrotna łączy dwie ostatnie wartości.

Wartość łagodzenia pozwala na użycie najpopularniejszych funkcji modyfikacji, które są już dobrze znane z CSS3, ponieważ można znaleźć ułatwienia, ułatwienia i tak dalej. Domyślnie każda animacja jest ustawiona na działanie liniowe, bez przyspieszania i zwalniania. Wartość wypełnienia określa, co zostanie zaprezentowane po zakończeniu animacji. Domyślnie animacja powinna powrócić do punktu początkowego. W przypadku użycia wartości forward animacja zatrzyma się na ostatniej klatce kluczowej.

Kontrola animacji

Użycie animate() na zmiennej pozwala nam kontrolować animację za pomocą JavaScript. Możemy go rozpocząć i zatrzymać według własnego uznania.

Animacja Var = document.getElementById("element").animate([
(wysokość: „0”),
(wysokość: „100%”)
], {
czas trwania: 3000,
iteracja: 2,
opóźnienie: 1000
});

document.getElementById("animation_start").addEventListener("kliknięcie", funkcja() (
animacja.play();
), FAŁSZ);

document.getElementById("animation_pause").addEventListener("kliknięcie", funkcja() (
animacja.pause();
), FAŁSZ);
Co dziwne, w naszym przykładzie dołączamy animację do zmiennej animacji. Następnie do elementów dołączamy 2 detektory zdarzeń o identyfikatorach animacja_start i animacja_pause. Ci słuchacze zajmą się wykonaniem określonych funkcji po kliknięciu. Play rozpoczyna animację, pauza jest już jasna, co robi, a rewers natychmiast przeniesie Cię do ostatniej klatki kluczowej i całkowicie zatrzyma animację.

Hej, to JavaScript. Oczywiście mamy detektor zdarzeń, który pozwala nam zareagować na koniec animacji. Możemy to zaimplementować za pomocą Finish. Wykończenie wewnętrzne wymaga zdefiniowania odpowiedniej funkcji.

Animacja.addEventListener("zakończ", funkcja() (
alert("Animacja się zakończyła.");
), FAŁSZ);
W powyższym przykładzie po prostu uruchamiamy komunikat informujący o zakończeniu animacji.

Obsługa przeglądarki

animate() jest obecnie we wczesnej fazie rozwoju i obecnie jest opatrzona etykietą „eksperymentalna”. Obsługa tej opcji pojawi się w przeglądarce Chrome począwszy od wersji 36. Jeśli chcesz wypróbować tę funkcję już teraz, możesz pobrać i zainstalować przeglądarkę Chrome Canary.

Adnotacja: Prosty przykład: metoda blaknięcia na żółto. Animacja z wykorzystaniem bibliotek JavaScript. Bardziej złożony przykład: przenoszenie i zmiana rozmiaru. Przejścia CSS.

Zasada zanikania polega na tym, że kolor tła zanikającego elementu jest ustawiany na żółty, a następnie w kilku etapach jego kolor powraca do pierwotnego koloru. Jeśli więc pierwotny kolor tła był czerwony, kolor zostanie następnie ustawiony na żółty, następnie pomarańczowo-żółty, następnie pomarańczowy, czerwono-pomarańczowy i wreszcie czerwony. Liczba zastosowanych kroków określa, jak płynnie następuje zmiana koloru, a czas między krokami określa, jak długo trwa zmiana koloru. Przy zmianie kolorów można wykorzystać przydatny fakt z CSS: kolor można zdefiniować jako trójkę liczb regularnych lub jako ciąg szesnastkowy. Dlatego #FF0000 (kolor czerwony) można również zdefiniować jako rgb(255,0,0) . Zmiana z żółtego na czerwony w pięciu krokach oznacza zatem przejście od rgb(255,255,0) (żółty) do rgb(255,0,0) w następujących pięciu krokach:

rgb(255,255,0) rgb(255,192,0) rgb(255,128,0) rgb(255,64,0) rgb(255,0,0)

Bardziej złożony przykład: przenoszenie i zmiana rozmiaru

Chociaż metoda żółtego blaknięcia demonstruje animację, jest nieco nudna. Kiedy większość ludzi myśli o animacji, zwykle myśli o ruchu. Ciekawa technika ostrzegania użytkownika, że ​​coś się wydarzyło, bez przeszkadzania mu przepływ pracy, składa się z niemodalnego komunikatu. Zamiast wyświetlać okno dialogowe alert(), które wymaga kliknięcia od użytkownika OK zanim będzie mógł kontynuować, umieść wiadomość w pływającym elemencie div na stronie, który dyskretnie pozostanie tam do czasu otrzymania potwierdzenia. Drugą dość interesującą rzeczą mogłoby być umożliwienie użytkownikowi powrotu do wiadomości, w przypadku której potwierdził, że chce ją ponownie przeczytać. Zaimplementujmy więc pływającą wiadomość, która po kliknięciu zwija się do rogu ekranu, a następnie można ją ponownie przywrócić po kliknięciu. Możesz obejrzeć krótkie demo tej „zapadającej się wiadomości” (http://dev.opera.com/articles/view/javascript-animation/moving_messages_jq.html), aby uzyskać ogólne pojęcie.

Jeśli zajmujesz się poważną animacją lub poważną pracą nad JavaScriptem, prawie zawsze warto skorzystać z biblioteki JavaScript. Umożliwi to stworzenie pożądanej prezentacji dla użytkowników bez konieczności martwienia się o zawiłości matematyczne wymagane do wykonania animacji. (Dzięki pierwszemu przykładowi powyżej wiesz już, jak wykonywać obliczenia matematyczne i jak używać setInterval , ale zaoszczędzisz czas i wysiłek, korzystając z gotowych rozwiązań.)

Powyższe demo wykorzystuje bibliotekę jQuery (http://jquery.com/), aby działało, ale jak wspomniano, większość bibliotek zapewnia na tyle podobną koncepcję animacji, że powinieneś być w stanie zaimplementować podstawową część przy użyciu preferowanej biblioteki. Zasadniczo musisz wykonać następujące czynności:

  1. Pokaż pływającą wiadomość na środku ekranu
  2. Po kliknięciu:
    1. Przesuń jego pozycję poziomą do skrajnie prawej pozycji
    2. Przesuń jego pozycję pionową w górę
    3. Ustaw jego szerokość na 20px
    4. Ustaw jego wysokość na 20px
    5. Ustaw jego gęstość na 20%, tak aby stała się prawie przezroczysta i ukryj znajdujący się w niej tekst
  3. Po kliknięciu tej „mini” wersji wiadomości przywróć ją na środek ekranu (tj. odwrotnie niż to zrobiliśmy, aby ją skompresować) i tak, aby użytkownik miał jasny obraz tego, co stało się z jego wiadomością, przeskakując od pełnego rozmiaru Wiadomości do mini-wiadomości powinny być animowane (aby mogły zobaczyć, jak wiadomość „zmniejsza się” do rogu okna).

Animowanie za pomocą jQuery jest bardzo proste: wystarczy użyć pliku . animować() i podaj pożądany efekt końcowy animacji (oraz czas jej trwania):

$(ourObject).animate((szerokość: "20px", wysokość: "20px", góra: "20px", prawa: "20px", marginesRight: "0px", krycie: "0.2" ), 300);

Funkcja pobiera naszObject i w ciągu 300 milisekund zastępuje jego szerokość i wysokość na 20 pikseli, górną i prawą pozycję na 20 pikseli, właściwość stylu prawego marginesu na 0 pikseli, a gęstość (w przeglądarkach obsługujących gęstość obrazu) na 20%. W takim razie pozostaje tylko kwestia programowania w dobrym stylu

Kiedyś większość programistów używała jQuery do animowania elementów w przeglądarce. Odbarwij to, rozciągnij tamto – proste rzeczy. Jednak w miarę jak projekty interaktywne stawały się coraz bardziej agresywne i pojawiały się urządzenia mobilne, najważniejszym czynnikiem stała się wydajność.

Flash stopniowo wypadał z łask, a utalentowani animatorzy sprawili, że HTML5 zrobił rzeczy, jakich nigdy wcześniej nie robił. Potrzebowali bardziej wydajnych narzędzi do uzyskania złożonych efektów i wydajności na najwyższym poziomie.

jQuery po prostu nie został do tego zaprojektowany. Przeglądarki dojrzały i zaczęły oferować rozwiązania.

Najbardziej znanym rozwiązaniem są animacje CSS. Animacja CSS, jako ulubieniec branży IT, od kilku lat jest bez przerwy omawiana na konferencjach, gdzie pojawiają się zwroty takie jak „ przyspieszenie sprzętowe" I " przyjazny dla urządzeń mobilnych„ – pieścił uszy publiczności.

Animacje oparte na JavaScript były postrzegane jako przestarzałe i „obsceniczne”. Ale czy tak jest naprawdę?

Jako osoba zafascynowana (właściwie z pogranicza obsesji) animacją i wydajnością, z zapałem rzuciłam się w ramiona CSS. Zanim zaszedłem daleko, pojawiło się wiele poważnych problemów, o których nikt nie mówił. Byłem zszokowany.

Celem tego artykułu jest zwrócenie uwagi na niektóre z najważniejszych wad animacji opartych na CSS, dzięki czemu możesz uniknąć problemów, których doświadczyłem, i podjąć bardziej świadomą decyzję o tym, kiedy używać JS do animacji, a kiedy używać CSS.

Brak niezależnej kontroli skali/rotacji/położenia

Animowanie skali, obrotu i położenia elementu jest niezwykle powszechne. W CSS wszystkie te parametry upchane są we właściwości transform, co uniemożliwia utworzenie osobnej animacji dla każdego parametru jednego elementu.

Na przykład, co jeśli chcesz wykonywać animacje rotacji i skalowania niezależnie od siebie, z różnymi obliczeniami czasu wykonywania i funkcjami wygładzania?

Być może element stale pulsuje (skala oscylacyjna) i chciałbyś go obrócić po najechaniu myszką. Jest to możliwe tylko dzięki JavaScript.

HTML:

Należy pamiętać, że skalę, obrót i położenie można animować niezależnie od siebie, korzystając z różnych funkcji wygładzania i nakładających się czasów rozpoczęcia i zakończenia (co nie jest możliwe w przypadku animacji CSS).

Niezależne konwersje

CSS:

body ( kolor tła: czarny; margines: 0; dopełnienie: 0; rodzina czcionek: Signika Negative, bezszeryfowa; waga czcionki: 300; ) html, treść ( wysokość: 100%; ) #demo ( display:table ; szerokość:100%; wysokość:100%; ) #field ( pozycja:względna; wyświetlacz:komórka tabeli; wysokość: 100%; przepełnienie:ukryty; wyrównanie tekstu: do środka; wyrównanie do pionu: środek; ) #box ( kolor: czarny; rozmiar czcionki: 24 piksele; dopełnienie: 10 pikseli 16 pikseli; obramowanie: 2 piksele jednolitej czerni; tło: #9af600; tło: gradient liniowy (do dołu, #9af600 0%, #71B200 100%); wyświetlacz: inline- blok; promień obramowania: 10px; ) #pole p ( pozycja: bezwzględna; kolor: #999; góra: 0 pikseli; dopełnienie: 0 pikseli 20 pikseli; wyrównanie tekstu: do lewej; indeks z: -1000; ) #kontrola ( pozycja: bezwzględny; kolor: #999; szerokość: 100%; dół: 20 pikseli; wyrównanie tekstu: do środka; ) przycisk ( margines: 2 piksele; )

JS:

var $box = $("#box"), $pole = $("#pole"), rotacja = 0, rotacjaX = 0, rotacjaY = 0, wanderTween, ignorowanieNajazdów; //zastosuj perspektywę do kontenera, abyśmy mogli zobaczyć 3D. TweenLite.set($pole, (perspektywa: 500)); //przesuń źródło wzdłuż osi z, aby obrót był bardziej interesujący. TweenLite.set($box, (transformOrigin:"środek-środek -150px")); //spraw, aby prostokąt pulsował za pomocą funkcji skalaX i skalaY TweenMax.to($box, 1.2, (skalaX:0.8, skalaY:0.8, force3D:true, yoyo:true, powtórz:-1, łatwość:Power1.easeInOut)); //po najechaniu myszą odwrócimy prostokąt, ale aby uniknąć // nadmiernego obrotu, zmniejszymy czułość najechania przez pierwszą sekundę //animacji. $box.hover(function() ( if (!ignoreRollovers) ( obrót += 360; ignorowanieRollovers = true; TweenLite.to($box, 2, (obrót:obrót, łatwość:Elastic.easeOut)); TweenLite.delayedCall( 1, funkcja() ( ignorowanieRollovers = false; )); ) ), funkcja() ()); $("#obrót").click(funkcja() ( obrót += 360; TweenLite.to($box, 2, (obrót:obrót, łatwość:Elastic.easeOut)); )); $("#rotationX").click(function() ( rotacjaX += 360; TweenLite.to($box, 2, (obrótX:obrótX, łatwość:Power2.easeOut)); )); $("#obrótY").click(funkcja() ( obrótY += 360; TweenLite.to($box, 2, (obrótY:obrótY, łatwość:Moc1.easeInOut)); )); $("#move").click(function() ( if (wanderTween) ( wanderTween.kill(); wanderTween = null; TweenLite.to($box, 0.5, (x:0, y:0)); ) else (wędrówka(); ) )); //wybierz losowo miejsce na ekranie i rozpocznij tam animację, a następnie powtórz tę czynność //raz po raz. funkcja wander() ( var x = (($field.width() - $box.width()) / 2) * (Math.random() * 1,8 - 0,9), y = (($field.height() - $box.height()) / 2) * (Math.random() * 1,4 - 0,7); wanderTween = TweenLite.to($box, 2,5, (x:x, y:y, łatwość:Power1.easeInOut, onComplete:wędrówka)); )

Moim zdaniem jest to wyraźnie słaby punkt CSS, ale jeśli tworzysz prostsze animacje, które obejmują całe transformacje w dowolnym momencie, nie będzie to dla ciebie problemem.

Wydajność

Większość porównań w Internecie porównuje animację CSS z biblioteką jQuery, ponieważ jest ona bardzo powszechna (jakby „JavaScript” i „jQuery” były synonimami), ale powszechnie wiadomo, że jQuery jest dość powolny pod względem wydajności animacji.

Nowsza biblioteka GSAP również opiera się na JavaScript, ale jest dosłownie 20 razy szybsza niż jQuery.Jednym z powodów, dla których JavaScript ma złą sławę, jest to, co nazywam „czynnikiem jQuery”.

Najczęściej cytowanym argumentem przemawiającym za używaniem CSS do animacji jest: „ przyspieszenie sprzętowe" Brzmi pysznie, prawda?

Podzielmy to na dwie części:

Zaangażowanie GPU

Jednostka przetwarzania grafiki (GPU) jest wysoce zoptymalizowany pod kątem takich zadań, jak przesuwanie pikseli, stosowanie przezroczystości i macierzy transformacji, dlatego nowoczesne przeglądarki starają się przenosić takie zadania z jednostki centralnej (CPU) na procesor graficzny.

Sekret polega na rozdzieleniu animowanych elementów na ich własne warstwy GPU, ponieważ po utworzeniu warstwy (o ile jej oryginalne piksele się nie zmieniają), GPU może z łatwością przenosić te piksele i łączyć je ze sobą.

Zamiast obliczać każdy pojedynczy piksel 60 razy na sekundę, procesor graficzny może przechowywać grupy pikseli (jako warstwy) i po prostu mówić: Przesuń tę grupę o 10 pikseli i 5 pikseli w dół" (Czy coś takiego).

Uwaga: nie jest rozsądne nadawanie każdemu elementowi własnej warstwy, ponieważ procesor graficzny ma ograniczoną pamięć wideo. Jeśli przekroczysz tę granicę, wszystko dramatycznie zwolni.

Deklarowanie animacji w CSS pozwala przeglądarce określić, które elementy powinny otrzymać warstwy GPU i odpowiednio je rozmieścić. Świetnie!

Ale czy wiesz, że dzięki JavaScript też możesz to zrobić? Ustawienie transformacji o charakterystyce 3D (takiej jak Translation3d() lub matrix3d() ) powoduje, że przeglądarka tworzy warstwę GPU dla tego elementu. Zatem zwiększenie szybkości procesora graficznego nie działa tylko w przypadku animacji CSS — animacje JavaScript również mogą na tym zyskać!

Należy również pamiętać, że nie wszystkie właściwości CSS są przyspieszane przez GPU w animacjach CSS. W rzeczywistości większość z nich nie otrzymuje tego przyspieszenia. Transformacje (skala, obrót, ścinanie i pochylenie) oraz przezroczystość to główne operacje, które korzystają z akceleracji GPU.

Więc nie myśl, że jeśli utworzysz animacje za pomocą CSS, wszystko w magiczny sposób zostanie przyspieszone przez GPU. To po prostu nieprawda.

Redystrybucja obliczeń do innego wątku

Inna część " przyspieszenie sprzętowe" odnosi się do możliwości wykorzystania różnych wątków procesora do obliczeń związanych z animacją. Ponownie brzmi to świetnie w teorii, ale nie jest pozbawione kosztów, a programiści często przeceniają uzyskane korzyści.

Po pierwsze, do innego wątku faktycznie można przekazać tylko te właściwości, które nie mają wpływu na przepływ dokumentu.

Zatem znowu głównymi beneficjentami są transformacja i przejrzystość. Gdy wątki są rozwidlane, zarządzanie tym procesem wiąże się z obciążeniem.

Ponieważ renderowanie grafiki i układ dokumentu pochłaniają większość mocy obliczeniowej (znacznie więcej) w większości animacji (nie licząc pośrednich wartości właściwości animacji), korzyść z użycia oddzielnego wątku do interpolacji jest minimalna.

Na przykład, jeśli 98% pracy podczas danej animacji polega na renderowaniu grafiki i układu dokumentu, a 2% na ustalaniu nowego położenia/obrótu/przezroczystości/jakichkolwiek wartości, a nawet obliczaniu ich 10 razy szybciej, w sumie zobaczysz tylko około Zwiększenie prędkości o 1%.

Porównanie wydajności

Poniższy test obciążeniowy tworzy określoną liczbę elementów obrazu (kropek) i wprawia je w ruch od środka do losowego miejsca w pobliżu krawędzi, stosując losowe opóźnienia, tworząc w ten sposób efekt lotu przez gwiazdy.

Ustaw dużą liczbę punktów i zobacz porównanie jQuery, GSAP i Zepto.

Ponieważ Zepto używa transformacji CSS dla wszystkich animacji, jego wydajność powinna być najlepsza, prawda?

HTML:

  • Silnik:
  • Nieruchomości:
  • Kropki:
  • POCZĄTEK
  • Testowanie szybkości animacji HTML5

    Porównaj wydajność animacji opartych na jQuery, GSAP (GreenSock Animation Platform) i transformacjach CSS (które są używane w Zepto). Wybierz powyższe opcje i naciśnij „START”. Zwiększaj liczbę kropek, aż zobaczysz nierówne ruchy lub grudki/okręgi. Zwróć także uwagę, które właściwości animują się szybciej: „top”, „left”, „width” i „height” lub „transform: Translation(...) skala(...)”. Możesz być zaskoczony.

    CSS:

    body ( kolor tła: czarny; margines: 0; dopełnienie: 0; kolor: #eee; rodzina czcionek: Signika Negative, bezszeryfowa; waga czcionki: 300; rozmiar czcionki: 1,15 em; wybór użytkownika: brak ; -webkit-user-select:none; ) html, body ( wysokość: 100%; przepełnienie:ukryty; ) h1 ( waga czcionki: 400; rozmiar czcionki:2em; wysokość-linii:1em; margines-dół:0.1 em; kolor: biały; ) a, a:hover, a:odwiedzono ( color:#71B200; ) #controls ( display:table-rows; kolor tła:#555; tło: gradient liniowy(do dołu, #777 0%,#444 100%); dopełnienie: 10px 10px 10px 5px; z-index:1000; ) #controls form li ( display:table-cell; padding:12px 6px 10px 6px; Vertical-align:middle;text-shadow : 1px 1px 1px #000; ) #instrukcje ( szerokość:82%; margines-lewy:8%; dopełnienie-góra:1em; wysokość linii: 1,5em; kolor:#ccc; ) #demo (display:table; szerokość :100%; wysokość:100%; ) #field ( pozycja:względna; wyświetlacz:komórka tabeli; szerokość:100%; wysokość: 100%; przepełnienie:ukryty; indeks Z: -100; górna granica: 1px pełna #777; ) #start (kolor: czarny; promień obramowania: 6px; dopełnienie: 5px 18px; obramowanie: 2 piksele w kolorze czarnym; tło: #9af600; tło: gradient liniowy (do dołu, #9af600 0%, #71B200 100%); kursor: wskaźnik; cień tekstu: brak; grubość czcionki: 400; )

    JS:

    var $start = $("#start"), $dotQtyInput = $("#ilośćdot"), $engineInput = $("#silnik"), $propertiesInput = $("#właściwości"), $instrukcje = $( "#instrukcje"), $pole = $("#pole"), $okno = $(okno), $wejścia = $("wybierz"), inProgress = false, testy = (), czas trwania, promień, środekX, centerY, kropki, rawDots, currentTest, startCSS; /** * Celem tego testu jest porównanie wydajności różnych narzędzi do animacji pod obciążeniem, wykonanie stosunkowo typowych zadań związanych z animacją i uruchomienie ich w dużej liczbie w celu sprawdzenia surowej wydajności. Celem nie jest znalezienie najskuteczniejszego sposobu przenoszenia punktów w układzie pola gwiazdowego. * * Ten sam kod jest używany we wszystkim z wyjątkiem samych animacji. Każdy test w obiekcie „test” posiada 4 właściwości: * * - milisekundy – true jeśli czas trwania ma być podany w milisekundach * * - wrapDot – gdy każdy punkt zostanie utworzony, należy go przekazać do metody wrapDot(), a to, co zwróci funkcja, zostanie zapisane w tablicy kropek na potrzeby animacji. Jest to przydatne do poprawy wydajności takich rzeczy jak jQuery, ponieważ zamiast przekazywać DOM elementu do metody tween() (co wymagałoby od jQuery wysłania zapytania do DOM i zawinięcia elementu w obiekt specyficzny dla silnika przed wywołaniem animate()) można wykorzystać obiekt naturalny. Mówiąc najprościej, umożliwi to buforowanie zawijania punktów w celu poprawy wydajności. * * - animacja jest podstawą całego testu. tween() jest wywoływana dla każdego punktu, punkt jest przekazywany jako parametr. Funkcja tween() powinna ustawić cssText punktu na początkową wartość CSS (która po prostu umieszcza punkt na środku ekranu i ustawia jego szerokość i wysokość na 1 piksel), a następnie po losowym opóźnieniu o 0 do czasu wykonania animacji, funkcja powinna animować punkt pod losowym kątem, zmieniając wartości lewe/górne lub transformacje translacji() i ustawiając rozmiar na 32 piksele szerokości i wysokości za pomocą opcji szerokość/wysokość lub skala(). Następnie, po zakończeniu animacji, należy ponownie wywołać metodę tween() w tym samym miejscu. Zatem ten sam punkt będzie po prostu stale oddalał się od środka pod losowym kątem i z losowym opóźnieniem. * * - stop – funkcja wywoływana gdy użytkownik zatrzyma test. Punkt jest przekazywany jako parametr. Funkcja powinna natychmiast zatrzymać/zniszczyć animację (lub animacje) działającą dla tego punktu (lub dla wszystkich punktów - to też jest normalne). * * - nativeSize – true jeśli początkowa szerokość/wysokość obrazków ma być naturalnej wielkości (zwykle jest to konieczne przy przekształceniach, ale nie wtedy, gdy animujemy szerokość/wysokość). * *Nie twierdzę, że jestem ekspertem w zakresie różnych silników animacji, więc jeśli istnieją optymalizacje, które można zastosować w celu poprawy wydajności testów, daj mi znać. Starałem się zrobić wszystko tak bezstronnie, jak to możliwe. **/ //standard jQuery normal (góra/lewo/szerokość/wysokość) tests.jquery_normal = ( milisekundy:true, wrapDot:function(dot) ( return jQuery(kropka); //zawijaj punkt w obiekcie jQuery, aby go ulepszyć wydajność (w ten sposób nie musimy odpytywać DOM za każdym razem, gdy animujemy - możemy po prostu wywołać animate() bezpośrednio na obiekcie jQuery), tween:function(dot) ( var angle = Math.random() * Math. PI * 2 ; dot.style.cssText = startCSS; dot.delay(Math.random() * czas trwania).animate((po lewej:Math.cos(kąt) * promień + środekX, góra:Math.sin(kąt) * promień + środekY , szerokość:32, wysokość:32), czas trwania, "cubicIn", funkcja() ( tests.jquery_normal.tween(dot) )); ), stop:funkcja(kropka) ( dot.stop(true); ), nativeSize :false); //standardowy GSAP (góra/lewo/szerokość/wysokość) tests.gsap_normal = ( milisekundy:false, wrapDot:function(kropka) (zwróć kropkę; //nie ma potrzeby zawijania), tween:function(kropka) ( var angle = Matematyka.random() * Matematyka. PI*2; dot.style.cssText = początkowy CSS; TweenLite.to(kropka, czas trwania, (css:(lewy:Math.cos(kąt) * promień + środekX, góra:Math.sin(kąt) * promień + środekY, szerokość:32, wysokość:32), opóźnienie:Math .random() * czas trwania, łatwość:Cubic.easeIn, nadpisz:"none", onComplete:tests.gsap_normal.tween, onCompleteParams:)); ), stop:funkcja(kropka) ( TweenLite.killTweensOf(kropka); ), nativeSize:false ); //Transformacje GSAP (translate()/scale()) tests.gsap_transforms = ( milisekundy:false, wrapDot:function(dot) (zwróć kropkę; // nie ma potrzeby zawijania), tween:function(dot) ( var angle = Math.random() * Math.PI * 2; TweenLite.set(kropka, (css:(x:0, y:0, skala:0,06), nadpisz: „brak”)); TweenLite.to(kropka, czas trwania , (css:(x:(Math.cos(kąt) * promień), y:(Math.sin(kąt) * promień), skalaX:2, skalaY:2), opóźnienie:Math.random() * czas trwania, easy:Cubic.easeIn, overwrite:"none", onComplete:tests.gsap_transforms.tween, onCompleteParams:)); ), stop:function(dot) ( TweenLite.killTweensOf(dot); ), nativeSize:true ); //standardowe testy Zepto (góra/lewo/szerokość/wysokość) zepto_normal = ( milisekundy:true, wrapDot:function(dot) ( return Zepto(kropka); // zawiń kropkę w obiekcie jQuery, aby poprawić wydajność (więc możemy nie ma potrzeby odpytywania DOM za każdym razem, gdy animujemy - możemy po prostu wywołać animate() bezpośrednio na obiekcie jQuery), tween:function(dot) ( var angle = Math.random() * Math.PI * 2; dot.style .cssText = startCSS; //Funkcja opóźnienia Zepto działa STRASZNIE pod presją, więc zamiast tego używamy setTimeout() w celu poprawy wydajności. setTimeout(function() ( if (!dot.isKilled) ( //Zepto nie ma funkcji, co pozwoliłoby nam zakończyć działające animacje, więc po prostu ustawiamy naszą właściwość isKilled na true, gdy animacja ma się zatrzymać, a następnie zatrzymujemy rekurencję, co daje nam potrzebny efekt. dot.animate((left:Math. cos(kąt) * promień + środekX, góra:Math.sin(kąt) * promień + środekY, szerokość:32, wysokość:32), czas trwania, "sześcienny-bezier(0,550, 0,055, 0,675, 0,190)", funkcja ( ) ( testy. zepto_normal.tween(kropka)); ) ), czas trwania * Math.random()); ), stop:function(kropka) ( dot.isKilled = true; ), nativeSize:false ); //Transformacje Zepto (translate()/scale()) tests.zepto_transforms = ( milisekundy:true, wrapDot:function(dot) ( return Zepto(dot); // zawiń kropkę w obiekcie jQuery, aby poprawić wydajność (więc możemy nie ma potrzeby odpytywania DOM za każdym razem, gdy animujemy - możemy po prostu wywołać animate() bezpośrednio na obiekcie jQuery) ), tween:function(dot) ( // Nie mogłem ustawić funkcji css() w Zepto (nie udało się ), więc musiałem użyć wywołania animate() o zerowym czasie trwania. Chociaż jest to uczciwe, ponieważ w przypadku TweenLite tak naprawdę tworzymy również animacje o zerowym czasie trwania. dot.animate((translateX:"0px", translacjaY:"0px", obrótY:"0rad", obrótX:"0rad", skala:"0,06,0,06"),0); //Funkcja opóźnienia Zepto działa STRASZNIE pod presją, więc zamiast tego używamy setTimeout() w celu poprawy wydajności. setTimeout(function() ( if (!dot.isKilled) ( //Zepto nie ma funkcji, która pozwala nam zakończyć działające animacje, więc po prostu ustawiamy naszą własną właściwość isKilled na true, gdy zakładamy, że animacja się zatrzymała, a następnie zatrzymaj rekurencję, co da nam pożądany efekt: var angle = Math.random() * Math.PI * 2; dot.animate((translateX:(Math.cos(kąt) * promień) + "px", tłumaczY:( Math. sin(kąt) * promień) + "px", skala: "2,2", opóźnienie: czas trwania * Math.random()), czas trwania, "cubic-bezier(0,550, 0,055, 0,675, 0,190)", funkcja( ) ( testy.zepto_transforms.tween(kropka); )); ) ), czas trwania * Math.random()); ), stop:function(dot) ( dot.isKilled = true; ), nativeSize:true ); funkcja toggleTest() ( var i, rozmiar; inProgress = !inProgress; if (inProgress) ( $inputs.prop("disabled", true); $field.css((pointerEvents:"none")); //poprawa wydajności – ignoruj ​​zdarzenia wskaźnika podczas animacji $start.html(" STOP "); $start.css((background:"#C00")); TweenLite.to($instructions, 0.7, (autoAlpha:0, overwrite:"all " )); currentTest = testy[$engineInput.val() + „_” + $propertiesInput.val()]; size = (currentTest.nativeSize ? „16px” : „1px”); centerX = $field.width( ) / 2; centerY = $field.height() / 2; startCSS = "pozycja:absolutna; lewa:" + centerX + "px; góra:" + centerY + "px; szerokość:" + rozmiar + "; wysokość: " + rozmiar + „;”; promień = Math.sqrt(centerX * centerX + centerY * centerY); czas trwania = currentTest.milisekundy ? 750: 0,75; //poczekaj milisekundę przed utworzeniem punktów i rozpoczęciem animacji, aby interfejs użytkownika odtwarzał do przodu ( zamiana przycisku „start” na „stop”), w przeciwnym razie użytkownicy mogą się zdezorientować podczas długiej pauzy podczas wybierania Zepto i konwersji, ze względu na fakt, że umieszczenie wszystkich kropek samodzielnie przez przeglądarkę może zająć trochę czasu warstwy. setTimeout(funkcja() ( createDots(); i = długość kropek; while (--i > -1) ( currentTest.tween(dots[i]); ) ), 1); ) else ( $start.html(" START "); $start.css((backgroundColor:"#9af600", tło: "linear-gradient(do dołu, #9af600 0%,#71B200 100%")); TweenLite .to($instrukcje, 0. 7, (autoAlfa: 1, opóźnienie: 0,2)); $inputs.prop("wyłączone", fałsz); kalibruj wejścia(); $field.css((pointerEvents:"auto")); //zatrzymaj animację i usuń punkty. i = długość kropek; while (--i > -1) ( currentTest.stop(dots[i]); $field.removeChild(rawDots[i]); //usuwa punkt (lub punkty) ) dots = null; rawDots = null; ) ) funkcja createDots() ( var i = parseInt($dotQtyInput.val()), kropka; dots = ; rawDots = ; while (--i > -1) ( dot = document.createElement("img"); kropka .src = "https://s3-us-west-2.amazonaws.com/s.cdpn.io/16327/dot.png"; szerokość kropki = 1; wysokość.kropki = 1; kropka.id = " kropka" + i; dot.style.cssText = startCSS; $field.appendChild(kropka); rawDots.push(kropka); dots.push(currentTest.wrapDot(kropka)); ) ) funkcja calibrateInputs(e) ( if ( $engineInput.val() === "jquery") ( //jQuery nie może animować transformacji bez wtyczki innej firmy, więc wyłącz tę opcję $propertiesInput.selectedIndex = 0; $propertiesInput.prop("disabled", true) ; ) else ( $propertiesInput.prop("wyłączone", fałsz); ) ) $start.click(toggleTest); $wejścia.zmiana(kalibracja wejść); jQuery.easing.cubicIn = $.easing.cubicIn =function(p, n,firstNum, diff) ( //musimy dodać standardową funkcję łagodzenia CubicIn do jQuery return FirstNum + p * p * p * diff; ) jQuery. stały interwał = 16; //zapewnia, że ​​jQuery aktualizuje się z częstotliwością około 60 klatek na sekundę, tak jak GSAP i inne, aby uzyskać bardziej równy/bezstronny wynik. $propertiesInput.prop("wyłączone", prawda);

    Wyniki potwierdzają to, co powszechnie odnotowuje się w Internecie – animacje CSS są znacznie szybsze niż jQuery.

    Jednak na większości urządzeń i przeglądarek, które testowałem, GSAP oparty na JavaScript ma jeszcze lepszą wydajność niż animacje CSS (w niektórych przypadkach z dużym marginesem, na przykład na Microsoft Surface RT, gdzie biblioteka GSAP była co najmniej 5 razy szybsza ) szybsze niż transformacje CSS utworzone w Zepto, a na iPadzie 3 z iOS7 transformacje były znacznie szybsze, gdy zostały wykonane przy użyciu GSAP zamiast transformacji CSS):

    Animowane właściwości Lepiej z JavaScriptem Lepiej z CSS
    góra, lewa, szerokość, wysokość Windows Surface RT, iPhone 5s (iOS7), iPad 3 (iOS 6), iPad 3 (iOS7), Samsung Galaxy Tab 2, Chrome, Firefox, Safari, Opera, Kindle Fire HD, IE11
    transformacje (przesunięcie/skala) Windows Surface RT, iPhone 5s (iOS7), iPad 3 (iOS7), Samsung Galaxy Tab 2, Firefox, Opera, IE11 iPad 3 (iOS6), Safari, Chrome

    O ile szybciej? Oryginalna wersja testu zawierała licznik klatek na sekundę zapewniający wyniki ilościowe, ale wkrótce odkryłem, że nie ma naprawdę dokładnego sposobu zmierzenia tego we wszystkich przeglądarkach, szczególnie w przypadku animacji CSS, a niektóre przeglądarki generowały wprowadzające w błąd dane, więc usunąłem tę funkcję.

    Chociaż względną wydajność można łatwo ocenić, zwiększając liczbę punktów, przełączając się między silnikami i obserwując, jak wykonywana jest animacja (płynność ruchu, równomierność odstępów czasowych, rozkład punktów itp.). W końcu głównym celem jest uzyskanie reprezentacyjnych animacji.

    Warto zauważyć:

    • Podczas animacji właściwości top/left/width/height (które wpływają na przepływ dokumentu) JavaScript był ogólnie szybszy (GSAP, nie jQuery);
    • Niektóre urządzenia były dobrze zoptymalizowane pod kątem transformacji, podczas gdy inne lepiej radziły sobie z animacjami z właściwościami góra/lewo/szerokość/wysokość. W szczególności starszy iOS6 znacznie lepiej wykonywał transformacje oparte na CSS, ale nowy iOS7 zmienił ich priorytety i jest teraz znacznie wolniejszy;
    • Występuje znaczne opóźnienie w początkowym uruchomieniu animacji opartych na CSS, ponieważ przeglądarka oblicza warstwy i ładuje dane do procesora graficznego. Dotyczy to również transformacji 3D w JavaScript, więc „akceleracja GPU” nie jest bezstratna;
    • Przy dużym obciążeniu CSS istnieje większe prawdopodobieństwo, że transformacje zostaną rozpryskane w paski lub pierścienie (jest to spowodowane problemami z synchronizacją i harmonogramem, prawdopodobnie z powodu kontroli w innym wątku).
    • W niektórych przeglądarkach (np. Google Chrome), gdy animacja obejmowała bardzo dużą liczbę punktów, w ogóle nie występowało stopniowe zanikanie tekstu, ale działo się to tylko przy zastosowaniu animacji CSS!

    Chociaż dobrze zoptymalizowany JavaScript jest często równie szybki, jeśli nie szybszy, niż animacje CSS, transformacje 3D są zazwyczaj renderowane przy użyciu CSS, ale jest to bezpośrednio powiązane ze sposobem, w jaki przeglądarki obsługują 16-elementowe macierze (wymuszając konwersję z liczb na połączone linie i potem z powrotem do liczb).

    Miejmy nadzieję, że to się jednak zmieni. Tak czy inaczej, w większości rzeczywistych projektów nigdy nie zauważysz różnicy w wydajności.

    Zachęcam Cię do przeprowadzenia własnych testów, aby sprawdzić, która technologia zapewni płynną animację w Twoim konkretnym projekcie (projektach).

    Nie wierz mitowi, że animacje CSS są zawsze szybsze i nie zakładaj, że powyższy test szybkości odzwierciedla to, co zobaczysz w swojej aplikacji. Testuj, testuj i jeszcze raz testuj.

    Kontrole wykonania i zdarzenia

    Niektóre przeglądarki umożliwiają zatrzymanie lub ponowne uruchomienie animacji za pomocą klatek kluczowych CSS, ale to wszystko.

    Nie możesz odnieść się do konkretnej lokalizacji w animacji, tak jak nie możesz płynnie zmienić kierunku sekcji animacji, zmienić osi czasu, dodać wywołań zwrotnych w określonych lokalizacjach lub powiązać ich z bogatym zestawem zdarzeń odtwarzania .

    JavaScript natomiast daje Ci dużą kontrolę, jak widać na poniższym przykładzie.

    HTML:

    Nie jest to możliwe w przypadku animacji CSS.
    Prędkość:

    CSS:

    body (rodzina czcionek: Signika Negative, bezszeryfowa; grubość czcionki: 300; kolor: biały; kolor tła: czarny; wyrównanie tekstu: środek; ) #demo ( wyrównanie tekstu: środek; margines-góra:20 pikseli ; ) #bg ( kolor tła: #000; pozycja: względna; przepełnienie: ukryty; wyświetlacz: blok inline; szerokość: 500 pikseli; wysokość: 70 pikseli; promień obramowania: 8 pikseli; obramowanie: 2 piksele stałe #777; ) #text ( pozycja:absolutna; wyrównanie tekstu: środek; szerokość: 500 pikseli; wysokość: 70 pikseli; wysokość linii: 68 pikseli; rozmiar czcionki: 28 pikseli; ) #text span ( -webkit-font-smoothing: antyaliasing; -moz-font- wygładzanie:antyaliasing; pozycja: względna; wyświetlacz: blok inline; kolor: #FFF; ) #slider ( display: blok inline; szerokość: 500 pikseli; wysokość: 12 pikseli; margines: 8 pikseli 0 pikseli 8 pikseli 6 pikseli; ) Przycisk #kontroli ( szerokość : 80px; ) #steruje wejściem ( display:inline; padding:2px; margines:2px; )

    JS:

    var $text = $("#tekst"), $pause = $("#pause"), $reverse = $("#reverse"), $restart = $("#restart"), $speed = $( "input"), $slider = $("#slider"), //"tl" to skala, do której dodamy naszą animację. //Wtedy możemy łatwo kontrolować całą sekwencję animacji jako jeden obiekt. tl = new TimelineLite((onUpdate:updateSlider, onComplete:onComplete, onReverseComplete:onComplete, wstrzymane:true)); funkcja updateSlider() ( $slider.slider("wartość", tl.progress() * 100); ) funkcja onComplete() ( tl.pause(); $pause.html("play"); ) //zrób coś proste dzielenie tekstu, abyśmy mogli zastosować animację do każdego //znaku (nie potrzebujesz zaawansowanych funkcji SplitText, więc po prostu użyj split() i //join()) $text.html(" " + $text.html().split("").join("").split("").join("") + ""); //ustaw perspektywę kontenera TweenLite.set($text, (perspektywa:500)); //cała animacja jest tworzona w jednej linii : tl. staggerTo($("#text span"), 4, (transformOrigin:"50% 50% -30px", obrótY:-360, obrótX:360, obrót:360, łatwość:Elastic.easeInOut), 0.02) ; // sterowanie suwakiem i przyciskiem $slider.slider(( zakres: fałsz, min: 0, max: 100, krok:.1, slajd: funkcja (event, ui) ( tl.progress(ui.value / 100). pauza() ; $pause.html("play"); ) )); $pause.click(function() ( if (tl.paused()) ( if (tl.progress() === 1 || ( tl.progress () === 0 && tl.reversed())) ( tl.restart(); ) else ( tl.resume(); ) $pause.html("pause"); ) else ( tl.pause (); $pause.html("resume"); ) )); $reverse.click(function() ( if (tl.progress() === 0) ( if (tl.reversed()) ( tl. play() ; ) else ( tl.reverse(0); ) $pause.html("pause"); ) else ( tl.reversed(!tl.reversed()).resume(); $pause.html(" pauza") ; ) )); $restart.click(function())( tl.restart(); $pause.html("pause"); )); $speed.change(function(v, val) ( tl.timeScale(parseFloat($(this).val())); if (tl.progress() === 1) ( tl.restart(); $pause .html("pause"); ) else if (tl.paused()) ( tl.resume(); $pause.html("pause"); ) ));

    Współczesna animacja w dużej mierze opiera się na interaktywności, dlatego niezwykle przydatna jest możliwość animacji od zmiennych wartości początkowych do zmiennych wartości końcowych (na przykład w zależności od tego, gdzie użytkownik kliknie) lub zmieniania czegoś w locie, ale animacje deklaratywne są oparte na CSS, nie pozwalają na to.

    Proces pracy

    W przypadku prostych przejść między dwoma stanami (na przykład przerzucanie lub rozwijanie menu itp.) transformacje CSS są świetne.

    Jednak w przypadku sekwencji zdarzeń zazwyczaj będziesz musiał użyć animacji CSS z klatkami kluczowymi, co będzie wymagało selektorów procentowych, na przykład:

    CSS:

    @keyframes myAnimation ( 0% ( krycie: 0; transformacja: tłumaczenie (0, 0); ) 30% ( krycie: 1; transformacja: tłumaczenie (0, 0); ) 60% ( transformacja: tłumaczenie (100px, 0); ) 100% ( transformacja: tłumacz(100px, 100px); ) ) #box ( animacja: myAnimation 2.75s; )

    Ale kiedy tworzysz animację, czy nie skupiasz się na przedziałach czasowych, a nie na wartościach procentowych? Na przykład, " zwiększ przezroczystość na 1 sekundę, następnie przesuń w prawo na 0,75 sekundy, a następnie zeskocz w dół na pozostałą sekundę».

    Co się stanie, jeśli spędzisz godziny na obliczaniu złożonej sekwencji procentów, a następnie klient powie: „ Wydłuż środkowa część o 3 sekundy„? Ugh, będziesz musiał przeliczyć WSZYSTKIE wartości procentowe!

    Zwykle tworzenie animacji wymaga wielu eksperymentów, zwłaszcza z funkcjami synchronizacji i wygładzania.

    Jest to istotne, gdy metoda poszukiwania() byłaby całkiem użyteczna. Wyobraź sobie, że tworzysz 60-sekundową animację kawałek po kawałku, a następnie dopracowujesz ostatnie 5 sekund: musiałbyś przeczekać pierwsze 55 sekund za każdym razem, gdy chciałeś zobaczyć wynik swoich poprawek w końcowych częściach.

    Uch! Dzięki metodzie szukaj() możesz po prostu odwołać się do określonej lokalizacji w animacji podczas pracy, aby dostać się do części, nad którą pracujesz, a następnie usunąć ją, gdy skończysz. Jest to znaczna oszczędność czasu.

    Tworzenie animacji dla obiektów opartych na kanwie i innych obiektów bibliotecznych innych firm staje się powszechne, ale niestety animacje CSS są przeznaczone tylko dla elementów DOM.

    Oznacza to, że jeśli zainwestowałeś dużo czasu i energii w animacje CSS, nie będzie można ich przenieść do innych typów projektów.

    Będziesz musiał zmienić zestaw narzędzi do animacji.

    Istnieje kilka innych przydatnych narzędzi związanych z przepływem pracy, których animacje CSS nie obejmują:

    • Wartości względne. Na przykład, " obrócić o 30 stopni więcej" Lub " przesuń element w dół o 100 pikseli od miejsca, w którym znajdował się w momencie rozpoczęcia animacji»;
    • Zagnieżdżanie. Wyobraź sobie, że możesz tworzyć animacje, które można zagnieździć w innej animacji, która sama może być zagnieżdżona itp. Wyobraź sobie, że kontrolujesz główną animację, podczas gdy wszystko inne pozostaje całkowicie zsynchronizowane. Taka struktura zachęcałaby do tworzenia kodu modułowego, który jest znacznie łatwiejszy w tworzeniu i utrzymaniu;
    • Status postępu. Czy dana animacja jest ukończona? Jeżeli nie, to na jakim etapie dokładnie jest realizacja?
    • Ukierunkowane eliminacje. Czasami niezwykle przydatne jest wyłączenie wszystkich animacji wpływających na skalę elementu (lub dowolnej innej pożądanej właściwości), jednocześnie zezwalając na wszystkie inne;
    • Krótki kod. Animacje CSS oparte na klatkach kluczowych są szczegółowe, nawet bez wszystkich wymaganych nadmiarowych wersji z prefiksami dostawcy. Każdy, kto próbował stworzyć cokolwiek nawet o umiarkowanej złożoności, potwierdzi fakt, że animacje CSS szybko stają się nieporęczne i niezgrabne. W rzeczywistości rzeczywista ilość kodu CSS wymagana do wykonania zadań animacyjnych może przekraczać wagę biblioteki JavaScript (którą łatwiej jest buforować i ponownie wykorzystywać w wielu animacjach).

    Ograniczone efekty

    Za pomocą animacji CSS nie będzie można wykonać żadnej z poniższych czynności:

    • Animacja wzdłuż krzywej (na przykład krzywa Beziera);
    • Skorzystaj z ciekawych funkcji zmiękczających, takich jak zmiękczanie elastyczne, sprężyste lub szorstkie. Istnieje opcja sześcienna-bezier(), ale uwzględnia ona tylko dwa kluczowe punkty, co jest bardzo ograniczające;
    • Ruchy zgodnie z prawami fizycznymi. Na przykład płynny ruch oparty na bezwładności i łatwy powrót, zaimplementowany w tym demo Przeciągania;
    • Animacja pozycji przewijania;
    • Obrót kierunkowy (na przykład „ obróć dokładnie o 270 stopni w najkrótszym kierunku, zgodnie z ruchem wskazówek zegara lub przeciwnie do ruchu wskazówek zegara»);
    • Animacja atrybutu.

    Zgodność

    Animacje oparte na CSS nie działają w IE9 i wcześniejszych wersjach przeglądarek. Większość z nas nie znosi zapewniania obsługi starszych przeglądarek (zwłaszcza IE), ale rzeczywistość jest taka, że ​​niektórzy z nas mają klientów, którzy tego wymagają.

    Stosowanie przedrostków jest konieczne w przypadku wielu przeglądarek, ale można użyć narzędzi do wstępnego przetwarzania, aby uniknąć konieczności ręcznego ich wpisywania.

    Wniosek

    Czy animacje CSS są złe? Absolutnie nie. W rzeczywistości świetnie nadają się do prostych zmian stanu (takich jak odwracanie), gdzie nie jest wymagana zgodność ze starszymi przeglądarkami.

    Transformacje 3D generalnie charakteryzują się dobrą wydajnością (iOS7 jest godnym uwagi wyjątkiem), a animacje CSS mogą być bardzo atrakcyjne dla programistów, którzy wolą umieścić całą logikę animacji i prezentacji w warstwie CSS.

    Jednak animacje oparte na JavaScript zapewniają znacznie większą elastyczność, wygodniejszy proces tworzenia złożonych animacji i bogatą interaktywność, a często animacje oparte na JavaScript są równie szybkie (lub nawet szybsze) niż animacje oparte na CSS, nawet jeśli możesz mieć usłyszał.

    Rozumiem, dlaczego animacje CSS były tak atrakcyjne w porównaniu z jQuery.animate() . Kto przy zdrowych zmysłach nie skorzystałby z okazji, aby uzyskać 10-krotny wzrost produktywności?

    Nie ma już potrzeby wybierania pomiędzy animacjami jQuery i CSS; narzędzia oparte na JavaScript, takie jak GSAP, otwierają zupełnie nowe możliwości i niwelują różnicę w wydajności.

    Ten artykuł nie dotyczy GSAP ani żadnej konkretnej biblioteki; Morał z tego artykułu jest taki, że animacje oparte na JavaScript nie zasługują na złą reputację. W rzeczywistości JavaScript jest jedyną opcją dla naprawdę solidnego i elastycznego systemu animacji.

    Ponadto chciałem rzucić trochę światła na niektóre frustrujące aspekty animacji CSS (o których nikt nie mówi), abyś mógł teraz podejmować bardziej świadome decyzje dotyczące tworzenia animacji.

    Czy specyfikacja Web Animations rozwiąże istniejące problemy?

    W3C pracuje nad nową specyfikacją zwaną „Animacjami sieciowymi”, która ma na celu usunięcie wielu niedociągnięć w animacjach i transformacjach CSS, zapewniając lepszą kontrolę wykonania i dodatkową funkcjonalność.

    Oczywiście wydaje się to krokiem do przodu pod wieloma względami, jednak nadal pozostaje szereg niedociągnięć (niektóre z nich są prawdopodobnie nie do pokonania ze względu na konieczność obsługi starszych wersji istniejących specyfikacji CSS, więc np. niezależna kontrola komponentów transformacji jest mało prawdopodobne).

    Choć to zupełnie inna historia. Musimy poczekać i zobaczyć, jak wszystko się ułoży. Z pewnością nad tą specyfikacją pracują mądrzy ludzie.

    Niniejsza publikacja jest tłumaczeniem artykułu „ Obalamy mity: animacje CSS vs. JavaScript”, przygotowany przez zaprzyjaźniony zespół projektowy

    Pod pojęciem „animacja” mamy na myśli najczęściej filmy animowane – czyli „kreskówki”, które kochamy od dzieciństwa. Ale jeśli zajrzymy do słownika objaśniającego, okaże się, że w tłumaczeniu z francuskiego oznacza „odrodzenie”, „animację”. I tutaj okazuje się, że to znaczenie zaskakująco trafnie pasuje nie tylko do branży filmowej, ale także technologii internetowych.

    Korzystanie z różnych efektów animacji(przejścia, ruchy, przekształcenia itp.) znacząco „ożywiają” witrynę, pozwalają zapanować nad uwagą użytkownika, przekierowując ją na żądany element i dając określone wskazówki wizualne.

    Mówiąc o animacji, nie można nie wspomnieć o dobrze znanych 12 zasadach sformułowanych przez animatorów studia Disneya, których stosowanie jest niezwykle ważne dla rozsądnego i wysokiej jakości wykorzystania efektów animacji.

    Mówiąc o technologiach, które zapewniają wykorzystanie animacji na stronach internetowych, można wyróżnić kilka, ale być może żaden z nich nie jest tak potężny jak . Jeszcze kilka lat temu technologia animacji Flash była poważnym konkurentem i bardzo popularna. Wydaje się jednak, że najlepsze lata ma już za sobą i stopniowo jest zastępowany ze stron witryn przez wydajniejsze i bardziej elastyczne skrypty Java. A jeśli zdecydujesz się poważnie użyj animacji na swojej stronie internetowej, to powinieneś postawić na JavaScript. Aby dokonać mądrego wyboru biblioteki, dokonałem dzisiejszej recenzji.

    Dynamics.js

    Prawdopodobnie zacznę od Dynamics.js. Jest to poważna i potężna biblioteka, która pozwala na tworzenie fizycznie realistycznych animacji (takich jak tłumione harmonicznie oscylacje punktu na stronie głównej witryny). Biblioteka jest w stanie zarządzać właściwościami dowolnego elementu DOM. Dynamics.js służy do tworzenia menu, przycisków, wskaźników procesów, znaczników. W tym przypadku dostępna jest szeroka gama parametrów, takich jak częstotliwość, ubytek tłumienia, parametry charakteryzujące sprężystość czy czas trwania procesu, itp.

    Cta.js

    Mała objętość biblioteka cta.js przeznaczony do tworzenia efektów animacji na stronie typu „akcja-efekt”, tj. najechanie lub kliknięcie wskaźnikiem myszy na obiekcie daje określony efekt. Jest bardzo wygodny w użyciu przy tworzeniu interfejsów kafelkowych, gdy kliknięcie na element powoduje jego otwarcie jako okna modalnego, na całej stronie lub jako boczny panel slajdu.

    Beep.js

    Ciekawa biblioteka wykorzystująca API WebAudio do tworzenia syntezatora muzycznego na stronie. Można go wykorzystać do tworzenia internetowego podręcznika muzycznego lub jako zabawną zabawkę.

    Rainyday.js

    Niesamowicie piękny efekt deszczu, po którym spływają krople o różnej wielkości. Jednak moim zdaniem dużym kroplom brakuje realizmu (może tej samej fizyki, która jest obecna w Dynamics.js?). Istniejące API pozwala jednak na tworzenie własnych obiektów i kontrolowanie ich zachowania, tworząc jeszcze bardziej niesamowite efekty.

    Dom-Animator.js

    Dom-Animator.js to tak zwany „jajko wielkanocne”. Efekt, jaki wywołuje, nie jest widoczny „gołym” okiem, tj. dla tych, którzy przeglądają stronę w zwykłym oknie przeglądarki. Ale ci, którzy analizują Twój kod, zobaczą go w konsoli (jeśli nadal nie rozumiesz, o czym mówimy, znajdziesz tutaj film, który wszystko wyjaśni).

    Słynny

    Sławny - napędzany wydarzeniami Biblioteka JS do tworzenia nowoczesnych animacji. Posiada potężny rdzeń geometryczny, który pozwala manipulować różnymi obiektami 3D – punktowymi i wolumetrycznymi – przykładać do nich siły i przyspieszenia, nakładać ograniczenia i kontrolować kolizje.

    Bounce.js

    Nie jest zły Biblioteka JavaScript do tworzenia imponujących animacji za pomocą CSS. Umożliwia zastosowanie różnego rodzaju ruchu, obrotu, skalowania i transformacji obiektów.

    Snabbt.js

    Lekka i szybka biblioteka, która według twórców zapewnia 60 klatek na sekundę nawet na urządzeniach mobilnych. Korzystając z macierzy transformacji, CSS umożliwia przesuwanie, obracanie, skalowanie i wykonywanie innych manipulacji obiektami. Umożliwia także nakładanie efektów specjalnych na obiekty przyciągające uwagę, co można wykorzystać podczas wypełniania formularzy.

    Rekapi

    Rekapi pozwala na użycie obu Animacja klatek kluczowych CSS(@reguła klatek kluczowych) i animacja DOM przy użyciu JavaScript. Biblioteka ta umożliwia tworzenie dość złożonych obiektów dynamicznych, takich jak wykresy kołowe i liniowe, osie czasu i inne elementy interfejsu użytkownika.

    Chytry

    Shifty to biblioteka zawierająca wszystko, czego potrzebujesz do pełnego animacja klatki kluczowej(tzw. „twinning”), a liczba obiektów może być po prostu ogromna. Jest to biblioteka niskiego poziomu, która może służyć jako rdzeń dla platform lub bibliotek wyższego poziomu. Właściwie Shifty jest używany jako rdzeń wspomnianego Rekapi.