7

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

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

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

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

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

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
  }
});

这是一个可以玩的小提琴。任何想法如何做到这一点?

4

2 回答 2

10

持续时间是按值传递的,而不是通过引用传递的。所以animate不存储对duration. 即使您更新了 jQueryoptions.duration内部使用的选项对象(通过引用传递),这意味着它将通过值传递。

作为快速修复,您可以停止动画并使用新的持续时间重新启动它 - 调整已经结束的动画部分。

您需要考虑您希望它的行为方式,例如当您将 4 秒动画加速到 3 秒后的 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/

于 2013-02-03T14:52:03.510 回答
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()应该每 13 毫秒调用一次,但由于没有任何保证,我认为持续时间应该至少增加 30 毫秒。
就我个人而言,我什至会选择至少 100 次。最好让动画运行时间过长(100 毫秒几乎不明显),而不是让它过早停止。

于 2015-10-03T16:24:26.267 回答