Change jQuery's animation duration during animating

左心房为你撑大大i 提交于 2019-12-04 04:51:24

The duration is passed by value, not by reference. So animate does not store a reference to duration. Even if you update the options object (which is passed by reference) jQuery uses options.duration internally, which means it will be passed by value.

As a quick fix you could stop the animation and restart it with the new duration - adjusting for the part of the animation that is already over.

You'd need to consider how you want it to behave, for example when you speed up a 4 second animation to a 2 second animation after 3 seconds. In the code below the animation will be immediate. Thinking about it, that's probably not what you want since you probably really care about speed, not duration.

The code below is a rough sketch, I'm not sure if it's accurate, if it works when decreasing animation values or how it handles multiple animation values. You can also only change the duration once.

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/

I'm probably a bit late for op but since I ended up here while trying to do the same thing, someone else may too.

On the start() callback jQuery pass the animation object as argument, so you just have to keep the reference somewhere and then you can change it on the step() callback.

Something like :

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

Now the tricky part is that jQuery decide to stop or continue the animation before calling the step() callback. So the duration is set for the next tick and if it wasn't set big enough your animation may be stopped.
jQuery use setInterval() with a interval of 13 so theoretically step() should be called every 13ms but since nothing is guaranteed I think duration should be increased by 30ms as a minimum.
Personally I would even go for at least 100. Better have an animation that runs a bit too long (100ms is almost unnoticeable) rather than having it to stop too soon.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!