2013-02-03 168 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几乎不明显),而不是让它停止过早。

相关问题