JQuery Animation: changing the mid-animation animation parameter

Suppose you had a long animation in which you changed width :

 var myTargetWidth = 500; $(el).animate( { "width" : myTargetWidth }, 5000 ); 

The animation is asynchronous, so your code continues., After a couple of seconds you decide to change the width target to 300 , The animation still works at this point.,.

How do I change targetWidth to another value in a running animation?

+7
source share
4 answers

One option is to use the step function specified in the jQuery animate ( API ) function to check the state during the animation.

JSFiddle example: http://jsfiddle.net/GweLA/13/

Js

 var myTargetWidth = 500; $(document).ready(function(){ $('.sample').animate( { "width" : myTargetWidth },{ duration : 5000, step: function(now, fx) { if($(this).width() > 200){ myTargetWidth = 300; $(this).stop().animate({ "width" : myTargetWidth },1000); } } }); }); 

CSS

 .sample{ width:20px; height:100px; background-color:#cccccc; } 

HTML

 <div class="sample"> width is supposed to be animated till 500 but it stops at 300 </div> 

Solution 2:

After some research, I found that we can change the start and end properties of the fx parameter passed to the step functions to control the animation. This kind of smooths the animation, but not a very neat way to do it, though.

JSFiddle example: http://jsfiddle.net/GweLA/57/

Js

 var myTargetWidth = 500; var isExecuted = false; $(document).ready(function(){ $('.sample').animate( { "width" : myTargetWidth },{ duration : 5000, queue : false, step: function(now, fx) { //So that fx.start and fx.end is set only once if($(this).width() > 200 && $(this).width() < 203){ if(!isExecuted){ fx.start = now-65; fx.end = 300; } isExecuted = true; } } }); }); 
+4
source

You can use a combination . stop () - stop the animation.

: animated selector - that checks if the current element is animated.

try it

HTML

 <div class="a"></div><button id="check">Check Animation </button>​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​ 

Javascript

 var myTargetWidth = 300; var $el = $('.a') $el.animate({ "width": myTargetWidth }, 5000); $('#check').on('click', function() { var newHeight = 300; if ($('.a:animated')) { $el.stop().animate({ "height": newHeight }, 5000); } });​ 

Check feed

+2
source

Looking at effects.js in jquery github, you will have problems changing the variable after assignment

Source: https://github.com/jquery/jquery/blob/master/src/effects.js

NOTE. Pay attention to creating and creating an object in .animate for animation (workhorse)

 animate: function( prop, speed, easing, callback ) { var empty = jQuery.isEmptyObject( prop ), optall = jQuery.speed( speed, easing, callback ), doAnimation = function() { // Operate on a copy of prop so per-property easing won't be lost var anim = Animation( this, jQuery.extend( {}, prop ), optall ); // Empty animations resolve immediately if ( empty ) { anim.stop( true ); } }; return empty || optall.queue === false ? this.each( doAnimation ) : this.queue( optall.queue, doAnimation ); } 

// Animation in effects.js

 function Animation( elem, properties, options ) { var result, index = 0, length = animationPrefilters.length, deferred = jQuery.Deferred().always( function() { // don't match elem in the :animated selector delete tick.elem; }), tick = function() { var currentTime = fxNow || createFxNow(), remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), // archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497) temp = remaining / animation.duration || 0, percent = 1 - temp, index = 0, length = animation.tweens.length; for ( ; index < length ; index++ ) { animation.tweens[ index ].run( percent ); } deferred.notifyWith( elem, [ animation, percent, remaining ]); if ( percent < 1 && length ) { return remaining; } else { deferred.resolveWith( elem, [ animation ] ); return false; } }, animation = deferred.promise({ elem: elem, props: jQuery.extend( {}, properties ), opts: jQuery.extend( true, { specialEasing: {} }, options ), originalProperties: properties, originalOptions: options, startTime: fxNow || createFxNow(), duration: options.duration, tweens: [], createTween: function( prop, end ) { var tween = jQuery.Tween( elem, animation.opts, prop, end, animation.opts.specialEasing[ prop ] || animation.opts.easing ); animation.tweens.push( tween ); return tween; }, stop: function( gotoEnd ) { var index = 0, // if we are going to the end, we want to run all the tweens // otherwise we skip this part length = gotoEnd ? animation.tweens.length : 0; for ( ; index < length ; index++ ) { animation.tweens[ index ].run( 1 ); } // resolve when we played the last frame // otherwise, reject if ( gotoEnd ) { deferred.resolveWith( elem, [ animation, gotoEnd ] ); } else { deferred.rejectWith( elem, [ animation, gotoEnd ] ); } return this; } }), props = animation.props; propFilter( props, animation.opts.specialEasing ); for ( ; index < length ; index++ ) { result = animationPrefilters[ index ].call( animation, elem, props, animation.opts ); if ( result ) { return result; } } createTweens( animation, props ); if ( jQuery.isFunction( animation.opts.start ) ) { animation.opts.start.call( elem, animation ); } jQuery.fx.timer( jQuery.extend( tick, { anim: animation, queue: animation.opts.queue, elem: elem }) ); // attach callbacks from options return animation.progress( animation.opts.progress ) .done( animation.opts.done, animation.opts.complete ) .fail( animation.opts.fail ) .always( animation.opts.always ); } 

As a result, I think you will need .stop and request animation with the changed variable, since you have little chance of accessing any of the variables in closing (someone will correct me)

0
source

I added an example here:

http://jsfiddle.net/Q3ZcQ/

Try clicking on the click here animation elements ...

I use the clearQueue() and stop() functions.

CSS #block {width: 100px; height: 100 pixels; background: red; }

HTML

 <p> <a id="clickme">Click here</a> </p> 

JQuery

 $('#clickme').not('.again').on('mouseup',function() { $(this).addClass('again'); $('#block').animate({ width: '400' }, 5000, function() { // Animation complete. }); }); $('.again').live('mousedown', function() { $(this).removeClass('again'); $('#block').clearQueue().animate({ width: '200', }, 500, function() { $('#block').stop(true, false); }); });​ <div id="block" />​ 
0
source

All Articles