-
Notifications
You must be signed in to change notification settings - Fork 715
[web-animations-1] Setting the target effect to null on a play-pending animation should probably not make it paused #2077
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
See also #2048 which seems related. |
We should probably make the procedure to update the target effect clear the current time in this case. |
Considering a few cases: a) Animation is running, set target effect to something non-null: b) Animation is running, set target effect to null: However, importantly in the above cases, even if we finish, if we were to subsequently set the target effect to something long enough, we'd resume playback. That is, we can recover from this change. c) Animation is play-pending, set target effect to something non-null: d) Animation is play-pending, set target effect to null: I have no idea why I suggested clearing the current time (presumably I meant to say hold time). That would make this idle which doesn't match the behavior for any of the other cases. What if we were to calculate the start time from the hold time (e.g. Making it become finished is consistent with (a) and (b). If we later set the target effect to something non-null I think we'd end up playing it--i.e. we can recover from the situation. We'd have effectively skipped the asynchronous playback however. (We could make the behavior when setting a non-null target effect on an animation with a null target effect trigger the async play procedure but generally we try to make setting properties not produce async behavior.) The other option that comes to mind is to simply let the animation remain play-pending until a new target effect is associated with it. I need to check what happens for pause-pending too. |
On further thought, maybe we should just not cancel pending tasks and let the animation start playing normally (i.e. let it progress to finish)? If you play an animation without a null target effect that's what would happen anyway. |
I started experimenting with just not canceling pending tasks in Firefox for this case and so far it seems to work well. (Code/test changes) |
Discussed this yesterday with @graouts, @stephenmcgruer, and @flackr and decided this was probably ok (i.e. dropping the cancelation step), provided that the promises resolve as expected. Given the following test: const anim = div.animate({ marginLeft: [ '0px', '100px' ] }, 1000);
console.group('Initial state');
console.log(`playState: ${anim.playState}`);
console.log(`pending: ${anim.pending}`);
console.groupEnd();
anim.ready.then(() => {
console.log('Ready promise resolved');
}).catch(() => {
console.log('Ready promise rejected');
});
anim.finished.then(() => {
console.log('Finished promise resolved');
}).catch(() => {
console.log('Finished promise rejected');
});
console.group('After setting effect to null');
anim.effect = null;
console.log(`playState: ${anim.playState}`);
console.log(`pending: ${anim.pending}`);
console.groupEnd();
requestAnimationFrame(() => {
console.log('Next frame');
}); (Codepen) Current Firefox gives:
With these changes we get:
The reason for the finished promise being resolved first is that when we update the effect, the spec says to:
which will bring us to:
So we'll end up with a microtask on the queue to resolve the finish promise that will be processed before the next frame where we resolve the ready promise. That's a little unexpected perhaps, but I think it kind of makes sense too (and trying to fix it would probably only complicate the model further). The other question we had was whether this arrangement would allow you to recover from the finished-pending state and go back to play-pending. For example, if you do: const anim = div.animate({ marginLeft: [ '0px', '100px' ] }, 1000);
anim.effect = null;
anim.effect = new KeyframeEffect(...); Are you play-pending at the end? The answer is yes. Adding the following to the above test: console.group('After setting effect to something else');
anim.effect = new KeyframeEffect(div, { marginLeft: [ '0px', '100px' ] }, 1000);
console.log(`playState: ${anim.playState}`);
console.log(`pending: ${anim.pending}`);
console.groupEnd(); I get:
Which seems like the behavior we want. Unless anyone has any objections, I'm going to go ahead and make this change. |
Tests will be updated/added upstream in Mozilla bug 1478266. |
Tests merged in web-platform-tests/wpt#12194 |
https://bugs.webkit.org/show_bug.cgi?id=191301 <rdar://problem/45838422> Reviewed by Dean Jackson. The issue w3c/csswg-drafts#2077 has changed the Web Animations API such that we no longer reset pending tasks when setting a null effect on an animation. * animation/WebAnimation.cpp: (WebCore::WebAnimation::setEffect): git-svn-id: http://svn.webkit.org/repository/webkit/trunk@237856 268f45cc-cd09-0410-ab3c-d52691b4dbfc
From @birtles on November 20, 2017 7:7
That's because in the procedure to update the target effect we have this step:
So, whereas we would previously have had a pending task and reported either "pending" (prior to recent spec changes) or "running" we now find ourselves without a pending task, with a current time, and without a start time, i.e. paused.
Intuitively though if we drop the effect we should either remain pending (i.e. "running") or go to the "finished" state -- probably depending on what happens when we subsequently attach a valid effect.
Copied from original issue: w3c/web-animations#207
The text was updated successfully, but these errors were encountered: