在动画制作过程中更改jQuery的动画持续时间

时间:2013-02-03 14:14:35

标签: jquery animation jquery-animate state duration

是否可以在两个不同的值之间更改当前运行的jQuery动画的duration

我尝试通过直接分配更改duration,但没有成功:

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

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

...甚至,更改fx.options.duration中的step - 方法不会影响正在运行的动画:

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 。 任何想法如何做到这一点?

2 个答案:

答案 0 :(得分:10)

持续时间按值传递,而不是通过引用传递。因此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/

答案 1 :(得分: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个。更好的动画有点太长(100毫秒几乎无法察觉),而不是让它过早停止。