Skip to content
This repository has been archived by the owner on Apr 12, 2024. It is now read-only.

Commit

Permalink
fix($animate): ensure ms durations are properly rounded
Browse files Browse the repository at this point in the history
Closes #5113
Closes #5162
  • Loading branch information
matsko committed Dec 5, 2013
1 parent d802ed1 commit 93901bd
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 1 deletion.
8 changes: 7 additions & 1 deletion src/ngAnimate/animate.js
Original file line number Diff line number Diff line change
Expand Up @@ -865,6 +865,7 @@ angular.module('ngAnimate', ['ng'])
var NG_ANIMATE_CSS_DATA_KEY = '$$ngAnimateCSS3Data';
var NG_ANIMATE_FALLBACK_CLASS_NAME = 'ng-animate-start';
var NG_ANIMATE_FALLBACK_ACTIVE_CLASS_NAME = 'ng-animate-active';
var ELAPSED_TIME_MAX_DECIMAL_PLACES = 3;

var lookupCache = {};
var parentCounter = 0;
Expand Down Expand Up @@ -1118,14 +1119,19 @@ angular.module('ngAnimate', ['ng'])
event.stopPropagation();
var ev = event.originalEvent || event;
var timeStamp = ev.$manualTimeStamp || ev.timeStamp || Date.now();

/* Firefox (or possibly just Gecko) likes to not round values up
* when a ms measurement is used for the animation */
var elapsedTime = parseFloat(ev.elapsedTime.toFixed(ELAPSED_TIME_MAX_DECIMAL_PLACES));

This comment has been minimized.

Copy link
@caitp

caitp Dec 5, 2013

Contributor

I still think it's probably a good idea to file a bug about this, if this isn't the expected behaviour. I'm way too tired to dive into the CSS3 spec at the moment, so I'm not sure

This comment has been minimized.

Copy link
@caitp

caitp Dec 5, 2013

Contributor

I am told by the #csswg that rounding/precision is implementation defined, so I guess there's nothing to do :< this kind of thing seems likely to cause problems on mobile though, where there may be a lot less consistency about timing accuracy and rounding direction

This comment has been minimized.

Copy link
@IgorMinar

IgorMinar Dec 6, 2013

Contributor

thanks for the update


/* $manualTimeStamp is a mocked timeStamp value which is set
* within browserTrigger(). This is only here so that tests can
* mock animations properly. Real events fallback to event.timeStamp,
* or, if they don't, then a timeStamp is automatically created for them.
* We're checking to see if the timeStamp surpasses the expected delay,
* but we're using elapsedTime instead of the timeStamp on the 2nd
* pre-condition since animations sometimes close off early */
if(Math.max(timeStamp - startTime, 0) >= maxDelayTime && ev.elapsedTime >= maxDuration) {
if(Math.max(timeStamp - startTime, 0) >= maxDelayTime && elapsedTime >= maxDuration) {
activeAnimationComplete();
}
}
Expand Down
21 changes: 21 additions & 0 deletions test/ngAnimate/animateSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2852,5 +2852,26 @@ describe("ngAnimate", function() {
$timeout.flush();
});
});

it('should round up long elapsedTime values to close off a CSS3 animation',
inject(function($rootScope, $compile, $rootElement, $document, $animate, $sniffer, $timeout, $window) {
if (!$sniffer.animations) return;

ss.addRule('.millisecond-transition.ng-leave', '-webkit-transition:510ms linear all;' +
'transition:510ms linear all;');

var element = $compile('<div class="millisecond-transition"></div>')($rootScope);
$rootElement.append(element);
jqLite($document[0].body).append($rootElement);

$animate.leave(element);
$rootScope.$digest();

$timeout.flush();

browserTrigger(element, 'transitionend', { timeStamp: Date.now() + 1000, elapsedTime: 0.50999999991 });

expect($rootElement.children().length).toBe(0);
}));
});
});

0 comments on commit 93901bd

Please sign in to comment.