Prosta animacja z wykorzystaniem SVG i JavaScript


7 grudnia 2013 / Michał Załęcki


Wykorzystując grafikę wektorową możemy osiągać bardzo ciekawe efekty małym nakładem pracy, na pewno jest to wygodniejsza forma niż dziesiątki kontenerów i setki linii kodu CSS. Przygotowałem efekt obracających się trybików. Animacja jest płynna przez co przyjemna dla oka i nie obciąża zanadto procesora. Nie jest to oczywiście pokaz wszystkich możliwości duetu SVG i JavaScript, ale może zainspiruje Cię do stworzenia prawdziwego działa sztuki.

SVG

Tym razem nie zaczniemy od kodu HTML, a od stworzenia trybiku. W tym celu użyjemy programu Inkscape. Interfejs jest intuicyjny, a obsługa samego programu dziecinnie prosta. Trybik stworzymy z koła i kształtu podobnego do prostokąta z zaokrąglonymi rogami jako ikona 64×64.

Gdy już stworzyliśmy kształt pozostało tylko skopiować do schowka jego ścieżkę (nie chodzi o ścieżkę do pliku, a ścieżkę kształtu). Edytor XML znajduje się w menu Edycja programu Inkscape.

HTML

Skoro mamy już ścieżkę możemy teraz utworzyć plik kod pliku SVG. Nie pójdziemy jednak na łatwiznę i nie skopiujemy dwukrotnie pliku SVG, gdyż to nie w naszym stylu. Stworzymy najpierw „szablon”, z którego będziemy korzystać tworząc trybiki.

Kolejnym krokiem będzie napisanie kodu właściwego dla każdego trybiku.

CSS

Jedyna sprawa, którą warto poruszyć przy tym banalnym kawałku kodu jest właściwość fill. Jeżeli nie używałeś wcześniej SVG to raczej się z nią nie spotkałeś. Odpowiada ona za wypełnienie kształtu.

JavaScript

Kod JavaScript też jest nieskomplikowany. Co 10ms obracamy trybiki o 1 stopień.

Jeżeli nie ograniczyłeś się tylko do kopiowania kodu to na pewno zauważyłeś, że w CSS nadaliśmy ikonom wymiary 128×128 pikseli, a mimo to działamy na nich tak jak by były czterokrotnie mniejsze. Dlaczego? Pamiętaj, że ikona została stworzona jako obraz o rozmiarach 64×64 piksele i to ten wymiar decyduje o tym jak przeglądarka potraktuje obraz.

Przydatne linki



5 odpowiedzi na “Prosta animacja z wykorzystaniem SVG i JavaScript”

  1. Comandeer pisze:

    http://css-tricks.com/svg-tabs-using-svg-shape-template/ ;) ale sam pomysł jest genialny.

    ciekawi mnie dlaczego format grafiki od wieków miał wbudowany w sobie system szablonów a HTML dochrapał się go dopiero ostatnio, pod postacią tagu template i link[rel=import]. inna rzecz, że SVG nigdy nie zdobył wcześniej takiej popularności (ciekawe czemu, prawda Microsoft?)

    wartałoby także zaznaczyć, że domyślnie SVG pracować powinien tylko w trybie XML a jego inlinowanie w HTML-u dostępne jest teoretycznie dopiero w HTML 5. no i przy większych zabawach z SVG możemy dojść do problemów z wydajnością (bo to DOM w końcu)

    co do samego JS – AFAIR minimalnym czasem odstępu dla timerów jest 20ms i żaden browser poniżej tego pułapu nie schodzi (stąd też takie usilne parcie na to, żeby Chrome i lisek w końcu wprowadziły wsparcie dla setImmediate, zwłaszcza, że polyfille dla nich działają szybciej od natywnej implementacji w IE…). zresztą dla animacji i tak istnieje requestAnimationFrame i to właśnie jego powinno się używać. w połączeniu z techniką delta timing pozwala tworzyć płynniejsze animacje (bo tutaj będziemy mieli przestój i już płynność wiadomo co trafi). no i zaciągnięcie jQuery dla ustawienia wartości CSS dwóch elementów mnie drażni. bardzo…

    • Niezastąpiony Comandeer :)

      Zmieniłem kod o tyle, by nie szukał za każdym razem trybika tylko zapisałem je w zmiennych. Patrząc prawdzie w oczy to przy większych zabawach z czymkolwiek dochodzimy do problemów z wydajnością (np. checkboxy wyświetlające piłkę, wrzucałem to na webroadowego facebooka kilka dni temu). Ja nie mam problemów z zejściem poniżej 10ms, ani na lisku, ani na IE11 na desktopie, ani na IE10 na telefonie. Korzystając z requestAnimationFrame, o ile się nie mylę, żegnamy się z IE9 więc sobie to odpuściłem na wstępie. Ja przy jQuery będę się upierał. Na tym prostym przykładzie z dwoma trybikami może faktycznie nie widać wyższości jQuery nad rozwiązaniem bez niej, ale na swojej stronie mam kilka takich trybików i mogę bez problemu przeprowadzić niejawną iterację. W „czystym” JS będę już musiał wprowadzić pętlę i tracę tym samym na prostocie kodu. Myślę, że do poradnika takie rozwiązanie bardziej przemawia do ludzi.

      • Comandeer pisze:

        wiem, że był problem z tym zejściem. no a requestFrameAnimation ma tą przewagę nad timerami, że korzysta z pętli rysującej (tej samej co CSS), więc AFAIR ma wspomaganie przez GPU. no i nie ma takiej rygorystycznej natury, co one co pomaga przy animowaniu.
        a co do IE 9 – polyfill jest banalny ;) window.requestAnimationFrame=function(fn){setTimeout(fn,1000/60);}; tak najprościej mówiąc
        a w jQuery pętli nie ma? ;) w JS przecież też można ładnie
        [].forEach.call(document.querySelectorAll(‚.nasze#trybiki’),function(t){t.setAttribute(‚transform’,’blabla’);});
        może nie jest aż tak pięknie jak w jQuery, ale wciąż czytelnie

      • Comandeer pisze:

        Jest problem z zejściem ;) Ale nie jest to próg 10ms, jak wcześniej sądziłem. Otóż minimalny czas oczekiwania w przypadku timerów jest określony w specyfikacji HTML5 i wynosi 4ms. https://developer.mozilla.org/en-US/docs/Web/API/window.setTimeout#Minimum.2F_maximum_delay_and_timeout_nesting

  2. piotrabc pisze:

    Hej! Jest szybszy sposób na trybik w Inkscape: Efekty -> Renderowanie -> Koło Zębate.
    Wtedy cała metoda staje się jeszcze szybsza.
    Przydatny art. Pozdrawiam

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *