Pokazywanie postów oznaczonych etykietą animation. Pokaż wszystkie posty
Pokazywanie postów oznaczonych etykietą animation. Pokaż wszystkie posty

czwartek, 18 sierpnia 2011

Animation, czyli jak sprawnie animować elementy strony

Poprzednio pisałem na temat animacji. Tym razem rozbudowałem tę funkcję o dodatkowe przydatne możiwości.

var Animation = function(fn, params){
  params = params || {};
  params = params.implicit({
    frames: 10,
    fn: function(){},
    t: 30,
    transition: null,
    at: 0
  });
  var frame = Math.round(params.at * params.frames);
  var progress;
  
  var run = (function(){
    return params.transition
      ? function(p){
          progress = p;
          fn.call(res, params.transition(progress), params);
        }
      : function(p){
          progress = p;
          fn.call(res, progress, params);
        };
  })();
  var iid = setInterval(function(){
    run( (++frame)/params.frames );
    if( frame >= params.frames ){
      clearInterval(iid);
      params.fn.call(res, params);
    }
  }, params.t);
  run( frame/params.frames );
  
  var res = {
    stop: function(execEndFn){
      execEndFn = execEndFn || false;
      clearInterval(iid);
      if( execEndFn ){
        params.fn.call(res, params);
      }
      return this.progress();
    },
    progress: function(){
      return progress;
    },
    toString: function(){
      return '[Animation: '+ Math.round(progress * 1e2) +'%]';
    }
  };
  return res;
};

Przede wszystkim funkcja (klasa) nie zwraca już identyfikatora zwracanego przez funkcję setInterval. Zamiast tego zwraca obiekt z dwiema (nie licząc metody toString nadpisującej tę domyślną dla obiektu) metodami.
Pierwsza metoda stop umożliwia zatrzymanie animacji. Wywołanie jej z pierwszym parametrem równym true spowoduje wywołanie również funkcji, wywoływanej w chwili normalnego zakończenia animacji. Przez normalne zakończenie rozumiemy odtworzenie animacji do końca.
Kolejna metoda zwracanego obiektu pozwala pobrać aktualny stan animacji z zakresu <0; 1>.
Dodatkowo do opisanych już wcześniej parametrów dodałem dwa następujące.
Transition - pozwala przekazać funkcję przejścia. Dzięki temu możemy w prosty sposób zrealizować np. łagodne rozpoczęcie i/lub zakończenie animacji.
Kolejny nowy parametr at jest nie mniej ciekawy. Pozwala bowiem on na rozpoczęcie animacji od zadanego etapu. Animacja z niezerową wartością dla tego parametru będzie trwała już krócej czyli nie będzie rozciągnięta na zadaną ilość klatek (frames) a zostanie ucięta, co pozwala na niesamowicie proste zaimplementowanie animacji, która może zostać w dowolnej chwili przerwana i odtworzona wstecz do punktu wyjściowego.

Na koniec dodam, że "klasa" korzysta z funkcji implicit, w celu ustawienia domyślnych parametrów wywołania funkcji.

poniedziałek, 6 czerwca 2011

Animacja jednostkowa

Animacja jednostkowa to funkcja którą napisałem, po to aby ułatwić sobie tworzenie animacji w swoich aplikacjach.
Nazywam ją tak, ponieważ umożliwia mi proste zbudowanie animacji dowolnej wielkości (właściwości obiektu) w prosty i elegancki sposób poprzez wywołanie mojej funkcji z parametrem - liczbą z zakresu od 0 do 1 włącznie, która określa aktualny stan animacji.
Poniżej zamieszczam kod tytułowej funkcji a zaraz za nim krótki opis sposobu używania.

var animation = function(fn, params){
  params = params || {};
  params = {
    frames: params.frames || 10,
    fn: params.fn || null,
    t: params.t || 30
  };
  var frame = 0;
  fn(0);
  var iid = setInterval(function(){
    fn( (++frame)/params.frames );
    if( frame >= (params.frames) ){
      clearInterval(iid);
      params.fn();
    }
  }, params.t);
  return iid;
};

Jak widać funkcja przyjmuje dwa parametry: wskaźnik do funkcji oraz obiekt opcjonalnych parametrów.
fn - to wskaźnik do głównej funkcji wykonawczej, która będzie decydowała o tym co będziemy animować.
Zmienna params przyjmuje 3 opcjonalne parametry:
- frames - ilość klatek animacji,
- t - interwał pomiędzy kolejnymi klatkami animacji,
- fn - funkcja, która zostanie wywołana zaraz po zakończeniu działania animacji.
Funkcja zwraca wartość Number zwracaną przez wbudowaną funkcję setInterval. Pozwala to na wcześniejsze zakończenie działania animacji.

// prosty kod pokazujacy sposob uzycia funkcji
animation(function(x){
  alert(x);
}, {
  frames: 10,
  fn: function(){
    alert('koniec');
  }
});

Jak widać funkcja jest niczym więcej jak wzbogaceniem funkcji setInterval o dodatkowe funkcjonalności.
Mimo wszystko potrafi bardzo uprościć pisany kod.
Do jej głównych zalet można zaliczyć:
- zwracany bieżący stan animacji mieszczący się zawsze w przedziale domkniętym <0; 1>,
- pierwsze wywołanie funkcji fn(0) jest wykonywane synchronicznie, w przeciwieństwie do zastosowania samej funkcji setInterval, gdzie na pierwsze wywołanie zadanej funkcji skrypt musi odczekać zadany czas. Dzięki temu unikniemy krótkotrwałych stanów nieustalonych przebiegu animacji,
- i wreszcie możliwość dodania wskaźnika do funkcji wywoływanej na zakończenie animacji - prosty sposób na wykrycie końca animacji bez żadnych dodatkowych instrukcji warunkowych.