Animacje w MooTools 1.3
17 października, 2010
Płynne animacje elementów to zagadnienie, które bardzo zbliżyło strony WWW oparte o (X)HTML i CSS do stron wykonanych we Flashu. Właściwie patrząc na to co oferuje CSS3 można śmiało stwierdzić, że istnieje coraz mniej efektów stworzonych we Flashu, których nie da się przerobić na efekty wykonane z użyciem JavaScript.
Zawsze doceniałem MooTools za duże możliwości przy tworzeniu animacji. Ponieważ od czasu MooTools 1.1 wiele się zmieniło, chciałbym odświeżyć temat w wydaniu MooTools 1.3.
Spis treści
- Klasy związane z animacją
- Budowa klasy Fx
- Sposoby łączenia animacji
- Klasy Fx.Tween i Fx.Morph
- Określanie przebiegu animacji
- Przykłady
- Podsumowanie
Klasy związane z animacją
Podstawę tworzenia animacji stanowi klasa Fx, klasy Fx.Tween oraz Fx.Morph to jej pochodne - tak samo zresztą jak wszystkie inne klasy z prefiksem Fx. Zatem podstawą do zrozumienia sposobu tworzenia animacji w MooTools jest poznanie zasad działania klasy Fx.
Przy czym klasy tej samodzielnie nie będziemy raczej używać - możemy przyjąć, że stanowi ona swoisty procesor do przeliczania wartości w czasie. Dopiero klasy takie jak wspomniane wcześniej Fx.Tween i Fx.Morph robią z tych obliczeń użytek w postaci animacji elementów.
Budowa klasy Fx
Klasa Fx implementuje interfejsy Chain, Events oraz Options. Konstruktor klasy Fx (i wszystkie pochodne klasy Fx) pobiera jako argument obiekt z opcjami w którym możemy określić następujące parametry:
- fps - określa ilość klatę na sekundę dla animacji - domyślnie 50;
- unit - określa jednostkę dla której wykonywane są obliczenia - przykładowo '%' lub 'px'. Użyteczne głównie wtedy kiedy nie zmieniają nam się wartości dla których wykonujemy animację a zmienia się jednostka. Domyślna wartość tego parametru to false;
- link - określa nam w jaki sposób są wywoływane kolejne animacje odnoszące się do danej instancji klasy Fx. Obszerniej opiszę ten parametr w dalszej części wpisu;
- duration - określa nam czas trwania animacji w milisekundach - domyślna wartość to 500. Warto wspomnieć, że możemy też podać ten parametr słownie: short (250ms), normal (500ms), long (1000ms)
- transition - określa nam sposób przeliczania animacji co wpływa na jej dynamikę w poszczególnych częściach animacji. Dokładniejszy opis tej opcji znajduje się w dalszej części tego wpisu;
Przykładowy obiekt definiujący animację 30fps o długości 150ms:
{
fps: 30,
duration: 150
}
W klasie Fx mamy do wykorzystania następujące rodzaje zdarzeń:
obiektKlasyFX.addEvent('start', function() {
console.log('Animacja rozpoczęta!');
});
albo (dzięki implementowaniu przez klasę Fx interfejsów Events i Options) w obiekcie opcji - w tym wypadku pamiętamy o dodaniu przedrostka "on" do nazwy zdarzenia:
{
fps: 30,
duration: 150,
onStart: function() {
console.log('Animacja rozpoczęta!');
}
}
Animacją sterujemy z użyciem pięciu metod:
start
Metoda ta rozpoczyna animację (i wywołuje zdarzenie onStart). Pobiera dwa argumenty: wartość początkową i końcową, przy czym możemy też określić tylko jeden argument i wtedy jest on traktowany jako wartość końcowa. Wartość początkową stanowi wtedy z reguły wartość bieżąca modyfikowanej właściwości elementu - takie użycie jest często wręcz niezbędne do uzyskania płynnej animacji (zdarza się, szczególnie po anulowaniu animacji, że wartość początkowa różni się od bieżącej wartości modyfikowanej właściwości elementu i mamy do czynienia ze skokową animacją wartości na początku). Przykładowe wywołania metody start:
obiektKlasyFx.start(0, 10);
obiektKlasyFx.start(10);
Drugi zapis jest też wygodny z tego względu, że unikamy pobierania bieżącej wartości danej właściwości elementu - klasa Fx robi to za nas.
set
Metoda set służy do ustawiania konkretnej wartości parametru, bez wykonywania animacji. Stosujemy ją głównie do zdefiniowania początkowych wartości przed rozpoczęciem animacji:
obiektKlasyFx.set(10);
cancel
Metoda cancel powoduje zaniechanie dalszego wykonywania animacji i wywołanie zdarzenia onCancel. Nie pobiera żadnych argumentów:
obiektKlasyFx.cancel();
W wypadku jej stosowania najczęściej korzysta się też z metody start wraz z jednym argumentem celem uniknięcia skokowej animacji.
pause i resume
Metodę tą wykorzystujemy do chwilowego zatrzymania animacji. Którą możemy wznowić metoda resume. Obie metody nie pobierają żadnych dodatkowych argumentów:
obiektKlasyFx.pause();
obiektKlasyFx.resume();
Sposoby łączenia animacji
Wszystkie metody zwracają obiekt klasy Fx zatem możemy stosować tzw. chaining. To właśnie z nim związana jest opcja link oraz zdarzenie onChainComplete. Opcja link przyjmuje trzy wartości:
- ignore - w tym wypadku jeżeli zażądamy wykonania przez obiekt klasy Fx animacji w czasie trwania innej animacji to nasze żądanie nie zostanie zrealizowane;
- cancel - z kolei w tym wypadku nasze nowe żądanie animacji od obiektu klasy Fx zostanie zrealizowane - poprzednia animacja zostanie anulowana;
- chain - w tym wypadku jest tworzony swego rodzaju stos animacji - każde kolejne żądania animacją są odkładane na ten stos i wykonywane wtedy kiedy poprzednie animacje zostały już wykonane. Gdy wszystkie animacje ze stosu się wykonają - wywoływane jest zdarzenie onChainComplete.
Klasy Fx.Tween i Fx.Morph
Wiemy już co oferuje nam klasa Fx - możemy zatem przejść do klas Fx.Tween oraz Fx.Morph, które robią prawdziwy użytek z klasy Fx.
Zacznijmy od podstawowej różnicy pomiędzy tymi klasami - Fx.Tween to klasa służąca do animacji pojedynczej właściwości elementu, natomiast klasa Fx.Morph potrafi modyfikować jednocześnie kilka właściwości elementu.
Składnia konstruktorów tych klas jest identyczna - poza obiektem opcji pobierany jest uchwyt do modyfikowanego elementu:
var efekt = new Fx.Tween(element, {/* tutaj dodatkowe opcje */});
var efekty = new Fx.Morph(element, {/* tutaj dodatkowe opcje */});
Możemy też zamiast uchwytu do elementu podać po prostu jego identyfikator jako obiekt typu String:
var efekt = new Fx.Tween('idElementu', {/* tutaj dodatkowe opcje */});
Istotna różnica pojawia się pomiędzy tymi klasami w wypadku użycia metod set i start (metody cancel, pause oraz resume wywołujemy tak samo jak w klasie Fx). Zacznijmy od metody set:
efekt.set('background', '#000');
efekty.set({
'background': '#fff',
'height': 100
});
Jak widać poza wartością musimy też określić właściwość elementu, którą modyfikujemy - w wypadku klasy Fx.Tween stosujemy po prostu dwa argumenty, a w wypadku klasy Fx.Morph wykorzystujemy obiekt w którym pary klucz-wartość są postaci właściwość-wartość.
Metoda start w klasie Fx.Tween wygląda analogicznie:
efekt.start("background", '#000', '#fff');
Oczywiście tutaj też istnieje możliwość podania tylko docelowej wartości właściwości:
efekt.start("background", '#fff');
W wypadku klasy Fx.Morph składnia się ciut bardziej komplikuje - przy określaniu docelowej wartości wciąż wszystko wygląda prosto i w sumie tak samo jak w wypadku metody set:
efekty.start({
'background': '#fff',
'height': 100
});
Natomiast jeżeli chcemy określić także wartość początkową, wtedy musimy zdefiniować wartość jako dwuelementową tablicę, której pierwszy element to wartość początkowa, a drugi to wartość końcowa:
efekty.start({
'background': '#fff',
'height': [50, 100]
});
Dodatkowo jeżeli w klasie Fx.Tween chcemy uniknąć wpisywania przy każdym wywołaniu metody nazwy modyfikowanej właściwości, możemy zdefiniować opcję property - wtedy każda operacja będzie dotyczyła tak zdefiniowanej właściwości obiektu.
Określanie przebiegu animacji
Przebieg animacji określami w opcji transition. Dostępne rodzaje animacji mamy opisane po prawej na tej stronie Każdy z tych rodzajów animacji udostępnia (poza typem linear) trzy odmiany:
- easeIn
- easeOut
- easeInOut
Jako wartość opcji transition możemy podać obiekt, na przykład:
Fx.Transitions.Sine.easeOut
lub skorzystać z uproszczonej składni:
'sine:out'
W wypadku animacji typu easeInOut zapisujemy:
'sine:in:out'
Dla celów poznawczych polecam jak zawsze niezawodne demo.
Możemy też tworzyć własne animacje z użyciem klasy Fx.Transition - zarówno definiując własne funkcje przebiegu animacji jak też modyfikując parametry już istniejących funkcji - Pow, Back oraz Elastic pobierają opcjonalnie drugi argument:
var przebiegAnimacji = new Fx.Transition(Fx.Transitions.Back, 1.8);
Przykłady
Teoria za nami - pora na przykłady praktyczne wykorzystujące prezentowane we wpisie informacje.
Przykład 1. Wykorzystanie różnych prędkości animacji:
var effect1 = new Fx.Tween('elm1');
$('example1-start').addEvent('click', function(){
effect1.options.duration = $('select1').get('value');
effect1.start('margin-left', 0, 300);
});
$('example1-reset').addEvent('click', function(){
effect1.set('margin-left',0);
});
Warto zwrócić uwagę na fragment modyfikujący czas trwania animacji - jak widać nie musimy definiować wartości opcji wyłącznie w konstruktorze.
Przykład 2. Modyfikacja kilku właściwości elementu z użyciem klasy Fx.Morph:
var effect2 = new Fx.Morph('elm2');
$('example2-start').addEvent('click', function(){
effect2.start({
'width': 300,
'height': 150,
'border': '3px solid #a00',
'background-color' : '#f00'
});
});
$('example2-back').addEvent('click', function(){
effect2.start({
'width': 100,
'height': 100,
'border': '1px solid #999',
'background-color' : '#ccc'
});
});
Przykład 3. Zastosowanie różnych sposobów łączenia animacji:
var effect3 = new Fx.Tween('elm3', {duration: 'long'});
$('example3-start').addEvent('click', function(){
effect3.options.link = $('select3').get('value');
effect3.start('margin-left', 300).start('background-color', '#0c0').start('border', '10px solid #000');
});
$('example3-reset').addEvent('click', function(){
effect3.set('margin-left', 0);
effect3.set('background-color', '#ccc');
effect3.set('border', '1px solid #999');
});
Przykład 4. Występowanie zdarzeń w trakcie animacji:
var effect4 = new Fx.Tween('elm4', {
duration: 2000,
link: 'chain',
onStart: function() {
$('elm4').appendText('onStart ');
},
onCancel: function() {
$('elm4').appendText('onCancel ');
},
onComplete: function() {
$('elm4').appendText('onComplete ');
},
onChainComplete: function() {
$('elm4').appendText('onChainComplete ');
}
});
$('example4-start').addEvent('click', function(){
effect4.start('margin-left', 300).start('background-color', '#0c0').start('border', '10px solid #000');
});
$('example4-pause').addEvent('click', function(){
effect4.pause();
});
$('example4-resume').addEvent('click', function(){
effect4.resume();
});
$('example4-cancel').addEvent('click', function(){
effect4.cancel();
});
$('example4-reset').addEvent('click', function(){
effect4.set('margin-left', 0);
effect4.set('background-color', '#ccc');
effect4.set('border', '1px solid #999');
$('elm4').empty();
});
Podsumowanie
Poznaliśmy podstawowy sposób tworzenia animacji w MooTools 1.3. W kolejnym wpisie skupię się na metodach animacji przypisanych do klasy Element, które umożliwiają nam naprawdę szybkie (wymagające minimum kodu) definiowanie animacji - szczególnie użyteczne przy tworzeniu prostych i standardowych efektów.
Komentarze do wpisu "Animacje w MooTools 1.3":
1.
n3m0 napisał(a):
17 października 2010, 15:49:44
Fajne, gdyby jeszcze tak procka nie żarło (obydwa cory na >= 80%...)
2.
Dziudek napisał(a):
17 października 2010, 16:15:26
W jakiej przeglądarce to testowałeś ? Bo aż z ciekawości sobie odpaliłem w Firefoksie i Chrome te dłuższe 6-sekundowe animacje i powyżej 27% mi nie skoczyło ani razu :>
3.
legalnycyklista napisał(a):
17 października 2010, 16:22:28
Dokładnie, Fx4b5 na najszybszym procesorze świata Atom 1,6 (-; dochodził chwilowo do 60%, zwykle 40-50%
4.
marsjaninzmarsa napisał(a):
17 października 2010, 23:38:56
Ja zużycia procka nie mierzyłem, ale na Chrome Mobile (Android 2.2, 1 GHz) chodzi bez przycinki. :)
5.
sprae napisał(a):
18 października 2010, 05:32:55
To nie musi być wina rzeczy o których myślicie. Czasem to wina kiepskich sterowników graficznych Intela (za dużo funkcji softwareowych), albo Xów (kiepskie funkcje rysowania). Dlatego lepiej często wypada na chrome, bo on sam renderuje co może w swoich procesach, a w 8 zleca to GPU.
6.
demonnnn napisał(a):
15 kwietnia 2011, 12:41:49
Nie lubię komentarzy odnośnie flasha jak to dzisiejsze niedokonczone html 5 i css 3(które de facto nawet nie są jeszcze standardem - prawie wszystko jest alfa ,beta itp.) mogą się z nim równać i co raz mniej jest rzeczy których nie da się zrobić w tych nowych technologiach.Otóż to nie prawda, dla mnie kogoś kto naprawdę zna się na flashu i na technologiach www jak css2,css3 ,html 4.01 ,html 5 to brzmi jak bzdura totalna.Każdy tak naprawdę pomija jeden taki mały szczególik związany z tym ,że flash to nie tylko gry,animacje,efekty w przeglądarce ,ale przede wszystkim potężny program DO TWORZENIA tej grafiki ,a czy jest coś takiego dla html 5 czy css 3 ?
Dodaj komentarz: