2013-02-03 165 views
6

是否有可能在兩個不同的值之間更改當前運行的jQuery動畫的duration在動畫過程中更改jQuery的動畫持續時間

我試圖通過直接分配改變duration,但沒有成功:

var timing = { duration: 4000 }; 
$(document).click(function (e) { 
    timing.duration = 1000; 
}); 

$('#foo').animate({top:200, left:200}, timing); 

......甚至,改變fx.options.durationstep - 方法不影響正在運行的動畫:

var state = false, 
$(document).click(function (e) { 
    state = true; 
}); 

$('#foo').animate({top:200, left:200}, { 
    duration: 4000, 
    step: function(now, fx){ 
    if(state) fx.options.duration = 1000; 
    console.log(fx.options.duration); // 1000 
    } 
}); 

這裏有一個fiddle玩耍。 任何想法如何做到這一點?

+0

如果您從jQuery 2.0切換到jQuery> = 1.7.2,它(有點)起作用。我想這與jQuery團隊對動畫相關功能所做的最新更改有關。 – Mahn

+0

@Mahn是的,謝謝!我注意到......我現在處於核心位置,試圖弄清楚如何擺弄出來! – yckart

回答

9

持續時間通過值傳遞,而不是通過引用。所以animate不存儲對duration的引用。即使更新選項對象(通過引用傳遞),jQuery在內部使用options.duration,這意味着它將按值傳遞。

作爲一個快速解決方案,您可以停止動畫並使用新的持續時間重新啓動它 - 調整已經結束的動畫部分。

你需要考慮你想如何表現,例如當你在3秒後加速4秒動畫到2秒動畫。在下面的代碼中,動畫將立即生效。考慮一下,這可能不是你想要的,因爲你可能真的關心速度而不是持續時間。

下面的代碼是粗略的草圖,我不確定它是否準確,如果它在減少動畫值或如何處理多個動畫值時有效。您也可以只更改一次。

var state = false, 
    duration = 8000; 

$(document).click(function (e) { 
    state = true; 
    duration = 1000; 
}); 
var animationCss = {top:200, left:200}; 
$('#foo').animate(animationCss, { 
    duration: duration, 
    step: function(now, fx){ 
     if(state) { 
      $("#foo").stop(); 
      var percentageDone = (fx.now - fx.start)/(fx.end - fx.start) 
      var durationDone = fx.options.duration * percentageDone; 
      var newDuration = duration - durationDone; 
      if (newDuration < 0) 
      { 
       newDuration = 0; 
      } 
      $("#foo").animate(animationCss, { duration: newDuration}) 

     } 
    } 
}); 

http://fiddle.jshell.net/5cdwc/3/

+0

是的,謝謝你的想法和解釋!不過,我認爲這個想法非常棒,在野外某處肯定會有更甜美的解決方法! – yckart

+0

@yckart有'easing'選項,但我不確定它是如何工作的,並且在開始動畫之前需要知道動畫速度。 –

+0

只要animationCss帶有絕對值(例如,不加+ = 50)並取決於您希望它的行爲如同他在答案中提到的@Matt一樣,這實際上可以很好地工作。你可以使它看起來很漂亮,將它包裝在一個插件中,這應該相對容易。 – Mahn

0

我可能是有點晚了運,但因爲我在這裏結束了,同時試圖做同樣的事情,其他人可能也。

start()回調jQuery傳遞動畫對象作爲參數,所以你只需要保持引用的地方,然後你可以改變它在step()回調。

喜歡的東西:

var animEnd = false; //this will be updated somewhere else 
var animObj; 
$().animate({ 
     width: '100%' 
    }, 
    { 
     start: function(animation){ 
      animObj = animation; 
     }, 
     step: function(now, tween){ 
      if(!animEnd) 
       //jquery set an interval of 13 but let's be safe 
       animObj.duration += 30; 

      //you can change the value of tween.pos aswell 
     } 
    } 
); 

現在棘手的問題是,jQuery的決定停止或致電step()回調之前繼續動畫。所以持續時間是爲下一個勾號設置的,如果設置得不夠大,您的動畫可能會停止。
jQuery使用setInterval(),間隔爲13,所以理論上step()應該每13ms調用一次,但由於沒有保證,我認爲持續時間應該增加至少30ms。
就我個人而言,我甚至會至少跑100次。最好有一個動畫運行時間太長(100ms幾乎不明顯),而不是讓它停止過早。

相關問題