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.

Brak komentarzy:

Prześlij komentarz