在动画期间更改 jQuery 的动画持续时间
Posted
技术标签:
【中文标题】在动画期间更改 jQuery 的动画持续时间【英文标题】:Change jQuery's animation duration during animating 【发布时间】:2013-01-18 08:44:57 【问题描述】:是否可以在两个不同的值之间更改当前运行的 jQuery 动画的duration
?
我尝试通过直接分配更改duration
,但没有成功:
var timing = duration: 4000 ;
$(document).click(function (e)
timing.duration = 1000;
);
$('#foo').animate(top:200, left:200, timing);
...甚至,更改step
-方法中的fx.options.duration
不会影响运行动画:
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 可以玩。 任何想法如何做到这一点?
【问题讨论】:
如果你从 jQuery 2.0 切换到 jQuery >= 1.7.2 它(有点)工作。我想这与 jQuery 团队最近对动画相关功能所做的更改有关。 @Mahn 是的,谢谢!我注意到了……我现在处于核心状态,试着弄清楚如何解决这个问题! 【参考方案1】:持续时间是按值传递的,而不是按引用传递的。所以animate
不存储对duration
的引用。即使您更新选项对象(通过引用传递)jQuery 内部使用options.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/
【讨论】:
是的,感谢您的想法和解释!这个想法很棒,但我认为,在野外的某个地方肯定有更甜蜜的解决方法! @yckart 有easing
选项,但我不确定它是如何工作的,以及是否需要在开始动画之前知道动画速度。
这实际上可以很好地工作,只要 animationCss 带有绝对值(例如,没有 +=50)并且取决于你希望它如何表现得像@Matt 在他的回答中提到的那样。你可以让它看起来很漂亮,将它包装在一个插件中,这应该相对容易做到。
顺便说一下,Matt 代码的一个分支是相对于完成百分比而不是绝对持续时间(基本上是替代行为):fiddle.jshell.net/4mFn4【参考方案2】:
我可能有点迟到了,但由于我在尝试做同样的事情时最终来到这里,其他人也可能。
在 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 毫秒几乎不明显),而不是让它过早停止。
【讨论】:
以上是关于在动画期间更改 jQuery 的动画持续时间的主要内容,如果未能解决你的问题,请参考以下文章