Strona główna » Poradniki » Grafika SVG » Kontrolowanie animacji

Kontrolowanie animacji

Wstęp

W dotychczas przedstawionym sposobie tworzenia animacji każda definicja określa stan atrybutu obiektu na początku i na końcu klatki. Tego typu definicje stają się mało wygodne w momencie, gdy dany obiekt porusza się wiele razy. Z każdym ruchem przybywa o dodatkowy obiekt animate, a potem jeszcze nie można się pomylić podczas ustawiania kolejności wywołania kolejnych klatek. Z pomocą przychodzi atrybut keyTimes.

Klatki czasu

Atrybut keyTimes umożliwia ustawienie różnych wartości atrybutu w czasie. Oznacza to, że nie trzeba teraz dla danego atrybutu tworzyć wielu oddzielnych definicji modyfikujących ten sam atrybut. Teraz wystarczy tylko jeden, aby z tego skorzystać wystarczy w obiekcie animate ustawić atrybut keyTimes oraz values na listę wartości. Lista wartości to wartości rozdzielone średnikiem.

keyTimes przechowuje wartości, które procentowo określają kiedy w trakcie wywoływania animacji ma zostać ustalona dana wartość. W ten sposób możliwe jest skrócenie lub wydłużenie animacji bez obawy, że zostanie ona ucięta lub obiekt przez pewien czas nie będzie nic robić. W przypadku użycia tego atrybutu dotychczas używane from i to są całkowicie ignorowane.

Rozpocznijmy na początku od prostego przykładu. Koło przedstawione poniżej porusza się po kwadracie.

Kod

Poniżej znajduje się kod razem z wyjaśnieniem:

  1. <svg
  2.   xmlns="http://www.w3.org/2000/svg"
  3.   xmlns:xlink="http://www.w3.org/1999/xlink"
  4.   width="200" height="200" viewBox="0 0 200 200">
  5.   <rect x="50" y="50" width="100" height="100" stroke="black" fill="none"/>
  6.   <circle cx="50" cy="50" r="30" fill="green">
  7.     <animate attributeName="cx"
  8.       dur="4s"
  9.       values="50; 150; 150; 50; 50"
  10.       keyTimes="0; 0.25; 0.5; 0.75; 1"
  11.       repeatCount="indefinite"/>
  12.     <animate attributeName="cy"
  13.       dur="4s"
  14.       values="50; 50; 150; 150; 50"
  15.       keyTimes="0; 0.25; 0.5; 0.75 ;1"
  16.       repeatCount="indefinite"/>
  17.   </circle>
  18. </svg>

(5.) Na płótnie znajduje się obiekt rect, który jest użyty w celu wyświetlenia czarnej linii oraz (6.) zielone koło. Animacje zostały zadeklarowane wewnątrz obiektu circle, dlatego nie ma potrzeby ustalania, który obiekt ma być animowany. Ponadto animacje nie mają swoich id, ponieważ się uruchamiane są równocześnie po załadowaniu strony.

Każda animacja określa (7.) co modyfikuje dana animacja, (8.) jej czas oraz (9.) jakie wartości przyjmuje w (10.) w poszczególnych momentach czasu. Warto zwrócić uwagę, że czas klatki podaje się procentowo względem całej animacji. (11.) Animacje mają wywoływać się w nieskończoność. Analogicznie dla (12. - 16) animacji względem osi Y.

Drobna zmiana

W przypadku takim jak powyżej wszystkie klatki są wywoływane w równych odstępach czasowych, dlatego nie trzeba podawać atrybutu keyTimes. Interpretator sam powinien określić ile będzie klatek i ile klatka powinna trwać jeśli wszystkie powinny trwać tyle samo czasu. W poniższym przykładzie dodatkowo został zmieniony czas animacji, aby pokazać, dlaczego klatki czasowe są podawane procentowo, a nie w konkretnych wartościach sekundy.

Jak widać animacja jest wykonywana dwa razy szybciej i wszystkie jej klatki zostały zachowane.

Kod

  1. <svg
  2.   xmlns="http://www.w3.org/2000/svg"
  3.   xmlns:xlink="http://www.w3.org/1999/xlink"
  4.   width="200" height="200" viewBox="0 0 200 200">
  5.   <rect x="50" y="50" width="100" height="100" stroke="black" fill="none"/>
  6.   <circle cx="50" cy="50" r="30" fill="green">
  7.     <animate attributeName="cx"
  8.       dur="2s"
  9.       values="50; 150; 150; 50; 50"
  10.       repeatCount="indefinite"/>
  11.     <animate attributeName="cy"
  12.       dur="2s"
  13.       values="50; 50; 150; 150; 50"
  14.       repeatCount="indefinite"/>
  15.   </circle>
  16. </svg>

Sposób przejścia

Domyślnie przejścia pomiędzy klatkami odbywają się w sposób płynny. Określa się to jako przejście linearne. Dla każdych dwóch kolejnych klatek wyliczana jest wartość [różnica wartości na końcach odcinka]/[czas przeznaczony na odcinek], dlatego prędkość na poszczególnych odcinkach jest stała, ale na różnych odcinkach może mieć inną wartość. W obiekcie animate taki sposób zachowania określa calcMode o wartości linear.

Innym sposobem poruszania się jest calcMode=paced. Jest to tryb w którym prędkość animacji jest przez całą animację identyczna. Konkretny czasy klatek są całkowicie ignorowane, a wyliczona prędkość odpowiada wartości [całkowita droga]/[całkowity czas]

Czasem jednak może zaistnieć potrzeba, aby dany obiekt zmieniał konkretną wartość nagle bez dodatkowych przejść pomiędzy wartościami. Wtedy calcMode należałoby ustawić na wartość discrete. Poniżej znajduje się tabela, która pokazuje różnice pomiędzy każdą z trzech rodzajów animacji:

linearpaceddiscrete

Warto zwrócić uwagę na to, że ustawienie wartości paced spowodowało zachwianiem animacji, ponieważ całkowita odległość do przebycia w czasie to 100 w obu współrzędnych i jest ona wykonywana z tą samą prędkością w obu współrzędnych w tym samym czasie.

Zadania

Zadanie 1

Napisz kod, który wyświetli grafikę przedstawioną poniżej. Czas trwania animacji to 6 sekundy. Cztery kolejne odcinki są pokonane w czasie 1s, 2s, 1s, 2s. W trakcie szybkiego przejazdu kolor koła zmienia się na zielony, a w trakcie wolnego na czerwony.

Zadanie 2

Napisz kod, który wyświetli grafikę przedstawioną poniżej.