From 801768386b9fd44f1282834449b4cd1ae1e8d593 Mon Sep 17 00:00:00 2001 From: Jeffery To Date: Mon, 11 Jun 2012 14:17:36 -0400 Subject: [PATCH] Fix #8109, percent animations; fix #11854, wrong this, close gh-808 --- src/effects.js | 30 ++++++++++++++++++++++++------ test/unit/effects.js | 18 ++++++++++++++++++ 2 files changed, 42 insertions(+), 6 deletions(-) diff --git a/src/effects.js b/src/effects.js index ff1c98d80..7aae8a414 100644 --- a/src/effects.js +++ b/src/effects.js @@ -7,20 +7,38 @@ var fxNow, timerId, animationPrefilters = [ defaultPrefilter ], tweeners = { "*": [function( prop, value ) { - var end, unit, + var end, unit, prevScale, tween = this.createTween( prop, value ), parts = rfxnum.exec( value ), - start = tween.cur(); + start = tween.cur(), + scale = 1, + target = start; if ( parts ) { end = +parts[2]; unit = parts[3] || ( jQuery.cssNumber[ prop ] ? "" : "px" ); // We need to compute starting value - if ( unit !== "px" ) { - jQuery.style( this, prop, (end || 1) + unit); - start = start * (end || 1) / tween.cur() || 0; - jQuery.style( this, prop, start + unit); + if ( unit !== "px" && start ) { + // Iteratively approximate from a nonzero starting point + // Prefer the current property, because this process will be trivial if it uses the same units + // Fallback to end or a simple constant + start = parseFloat( jQuery.style( tween.elem, prop ) ) || end || 1; + + do { + // If previous iteration zeroed out, double until we get *something* + // Use a string for doubling factor so we don't accidentally see scale as unchanged below + prevScale = scale = scale || ".5"; + + // Adjust and apply + start = start / scale; + jQuery.style( tween.elem, prop, start + unit ); + + // Update scale, tolerating zeroes from tween.cur() + scale = tween.cur() / target; + + // Stop looping if scale is unchanged or we've hit the mark + } while ( scale !== 1 && scale !== prevScale ); } tween.unit = unit; diff --git a/test/unit/effects.js b/test/unit/effects.js index 9e244490d..48793e234 100644 --- a/test/unit/effects.js +++ b/test/unit/effects.js @@ -1628,4 +1628,22 @@ asyncTest( "multiple unqueued and promise", 4, function() { }); }); +asyncTest( "animate does not change start value for non-px animation (#7109)", 1, function() { + var parent = jQuery( "
" ).css({ width: 284, height: 1 }).appendTo( "#qunit-fixture" ), + child = parent.children().css({ fontSize: "98.6in", width: "0.01em", height: 1 }), + actual = parseFloat( child.css( "width" ) ), + computed = []; + + child.animate({ width: "0%" }, { + duration: 1, + step: function() { + computed.push( parseFloat( child.css( "width" ) ) ); + } + }).queue( function( next ) { + equal( computed[0], actual, "Starting width was unchanged" ); + next(); + start(); + }); +}); + } // if ( jQuery.fx ) -- 2.39.5