Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change jQuery's animation duration during animating

Is it possible to change the duration of a currently running jQuery animation between two different values?

I've tried to change the duration via direct assignment, but no success:

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

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

...and even, changing the fx.options.duration in step-method does not affect the running animation:

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

Here's a fiddle to play around. Any ideas how this can be done?

like image 344
yckart Avatar asked Feb 03 '13 14:02

yckart


People also ask

How do I increase the duration of an animation?

To run your animation effect at a faster or slower pace, change the Duration setting. On the slide, click the text or object that contains the animation effect that you want to set the speed for. On the Animations tab, in the Duration box, enter the number of seconds that you want the effect to run.

What is the correct syntax of animate () method?

The jQuery animate() method is used to create custom animations. Syntax: $(selector).animate({params},speed,callback);

Can the animate () method be used to animate any CSS property?

The animate() method performs a custom animation of a set of CSS properties. This method changes an element from one state to another with CSS styles. The CSS property value is changed gradually, to create an animated effect. Only numeric values can be animated (like "margin:30px").

Which jQuery method is used to stop an animation before it is finished?

The jQuery stop() method is used to stop an animation or effect before it is finished. The stop() method works for all jQuery effect functions, including sliding, fading and custom animations. Syntax: $(selector).


1 Answers

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/

like image 115
Matt Zeunert Avatar answered Sep 24 '22 17:09

Matt Zeunert