var fxNow, timerId,
rfxtypes = /^(?:toggle|show|hide)$/,
- rfxnum = /^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,
+ rfxnum = /^(?:([\-+])=)?([\d+.\-]+)([a-z%]*)$/i,
rrun = /queueHooks$/,
animationPrefilters = [ defaultPrefilter ],
tweeners = {
var end, unit, prevScale,
tween = this.createTween( prop, value ),
parts = rfxnum.exec( value ),
- start = tween.cur(),
- scale = 1,
- target = start;
+ target = tween.cur(),
+ start = +target || 0,
+ scale = 1;
if ( parts ) {
end = +parts[2];
// 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.css( tween.elem, prop ) ) || end || 1;
+ start = jQuery.css( tween.elem, prop, true ) || end || 1;
do {
// If previous iteration zeroed out, double until we get *something*
// Update scale, tolerating zeroes from tween.cur()
scale = tween.cur() / target;
- // Stop looping if scale is unchanged or we've hit the mark
+ // Stop looping if we've hit the mark or scale is unchanged
} while ( scale !== 1 && scale !== prevScale );
}
tween.unit = unit;
tween.start = start;
// If a +=/-= token was provided, we're doing a relative animation
- tween.end = parts[1] ? start + end * ( parts[1] === "-=" ? -1 : 1 ) : end;
+ tween.end = parts[1] ? start + ( parts[1] + 1 ) * end : end;
}
return tween;
}]
});
});
-asyncTest("Animation callbacks (#11797)", 12, function() {
+asyncTest( "non-px animation handles non-numeric start (#11971)", 2, function() {
+ var foo = jQuery("#foo"),
+ initial = foo.css("backgroundPositionX");
+
+ foo.animate({ backgroundPositionX: "42%" }, {
+ duration: 1,
+ progress: function( anim, percent ) {
+ if ( percent ) {
+ return;
+ }
+
+ if ( parseFloat( initial ) ) {
+ equal( jQuery.style( this, "backgroundPositionX" ), initial, "Numeric start preserved" );
+ } else {
+ equal( jQuery.style( this, "backgroundPositionX" ), "0%", "Non-numeric start zeroed" );
+ }
+ },
+ done: function() {
+ equal( jQuery.style( this, "backgroundPositionX" ), "42%", "End reached" );
+ start();
+ }
+ });
+});
+
+asyncTest("Animation callbacks (#11797)", 15, function() {
var targets = jQuery("#foo").children(),
done = false,
expectedProgress = 0;
targets.eq( 0 ).animate( {}, {
duration: 1,
+ start: function() {
+ ok( true, "empty: start" );
+ },
progress: function( anim, percent ) {
equal( percent, 0, "empty: progress 0" );
},
}
});
- ok( done, "animation done" );
+ ok( done, "empty: done immediately" );
done = false;
targets.eq( 1 ).animate({
opacity: 0
}, {
duration: 1,
+ start: function() {
+ ok( true, "stopped: start" );
+ },
progress: function( anim, percent ) {
equal( percent, 0, "stopped: progress 0" );
},
}
}).stop();
- ok( done, "animation stopped" );
+ ok( done, "stopped: stopped immediately" );
targets.eq( 2 ).animate({
opacity: 0
}, {
duration: 1,
+ start: function() {
+ ok( true, "async: start" );
+ },
progress: function( anim, percent ) {
equal( percent, expectedProgress, "async: progress " + expectedProgress );
// once at 0, once at 1