2011-08-19 49 views
1

我開始在JS中編寫一個簡單的動畫類,該類使用Zepto.js動畫功能,但增加了時間線功能。JavaScript時間軸動畫(setTimeout準確性問題)

的時間表本身是一個簡單的數組,當它的play()函數被調用執行嵌入在它的功能:

play : function(callback){ 

     for(var i=0; i<Animator.timeline.buffer.length; i++){ 

      Animator.timeline.buffer[i].animation(); 

     } 

     if(callback){ 
      callback(); 
     } 

    } 

的setTimeout的直接進入動畫:

alpha : function(parameters, callback, delay){ 

    var target = parameters.target; 
    var duration = parameters.duration; 
    var easing = parameters.easing; 
    var value = parameters.value; 

    if(delay){ 
     setTimeout(function(){run();},delay*1000); 
    } else { 
     run(); 
    } 

    function run(){ 
     $(target).anim({opacity:value},duration,easing); 
     if(callback){ 
      callback(); 
     } 
    } 


} 

所以基本上,時間線只是運行放置在緩衝區數組中的setTimeout-ed函數。

這種方法(幾乎)與WebKit動畫一樣符合預期,但在執行圖像序列(使用setInterval更改圖像的src的動畫)時遇到了一些問題。由於JS定時器不能保證在指定的時間內執行,有時候動畫運行會延遲,可能是因爲它們中嵌入了setInterval。

關於如何解決這個問題的任何想法?我意識到將所有動畫嵌入到另一個動畫中會解決很多問題,但我不知道如何在時間線循環內執行此操作。另外,如果我以直接方式調用所有函數(不使用時間軸),它很快就會變成一堆無法讀取的回調。

僅供參考,我的動畫類的順序功能:

sequence : function(parameters, callback, delay){ 

    var target = parameters.target; 
    var path = parameters.path; 
    var baseName = parameters.baseName; 
    var digits = parameters.digits; 
    var extension = parameters.extension; 
    var frames = parameters.frames; 
    var loop = parameters.loop; 

    if(parameters.interval){ 
     var _interval = parameters.interval 
    } else { 
     var _interval = 15; 
    } 


    var currentFrame = 0; 
    var imageUrl = ''; 

    var fileName = baseName; 

    for(var i=0; i<=digits; i++){ 
     fileName+='0'; 
    } 

    if(delay){ 
     setTimeout(function(){runSequence();},delay*1000); 
    } else { 
     runSequence(); 
    } 

    function runSequence(){ 

     var interval = setInterval(function(){ 

     if(currentFrame >= frames){ 
      currentFrame = 0; 
      if(!loop) { 
       clearInterval(interval); 
       if(callback){ 
        callback(); 
       } 
      } 
     } else { 
      imageUrl = path+fileName.substring(0, fileName.length-currentFrame.toString().length)+currentFrame+"."+extension; 
      $(target).attr('src',imageUrl); 
      currentFrame++; 
     } 

    },_interval); 

    } 

} 

此外,通過使用這個類創建動畫的一個樣本:

Animator.timeline.append(function(){ 
       Animator.alpha({'target':'#logo', 'value':1, 'duration':1, 'easing':'ease-out' }); 
      }); 

      Animator.timeline.append(function(){ 
       Animator.sequence({'target':'#sequence', 'path':'images/sequences/index/', 'baseName':'nr1_', 'digits':3, 'extension':'png', 'frames':50},'',1.5); 
      }); 

      Animator.timeline.append(function(){ 
       Animator.scale({'target':'#text', 'width':.5, 'height':.15, 'duration':1, 'easing':'ease-in-out'},'',3.2); 
      }); 

      Animator.timeline.append(function(){ 
       Animator.alpha({'target':'#link', 'value':1, 'duration':1,'easing':'ease-out'},'',4.7); 
      }); 

      Animator.timeline.play(); 

作爲附加的註釋,我的目標在AS3中創建類似GreenSock的東西,如果有幫助的話。

謝謝。

回答

1

準確的setInterval可以通過補償它需要執行每次迭代的時間進行模擬,也許這要點我寫可以幫助你:

https://gist.github.com/1185904

+0

你,先生,只是解決了一個巨大的問題對我來說。我真誠地感謝你。 – dbozhinovski