-
Notifications
You must be signed in to change notification settings - Fork 707
[web-animations] Could commitStyles always write the end state of the animation? #5394
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
That's an interesting proposal. It certainly seems feasible to add a flag to From my understanding, the proposal would be to effectively seek to the target effect end (but without firing events etc.), force the fill mode for all associated effects to Understanding the use cases would give a better idea of whether this should be two separate flags or not (e.g. one to seek to the target end, one to force the fill mode). It would also give a better idea of the priority of this feature. |
My application is a large state graph of vertices and edges. Each state transition animates the entire graph so the destination vertex (new current state) is centered in the view box. The new position of the graph needs to persist. There's a timeline slider to play the transitions from any point forward and backward. |
It seems like what this case needs is something like: function finishTransition(anim) {
// Make sure finish() seeks to the target effect end
anim.playbackRate = 1;
anim.finish();
anim.effect.updateTiming({ fill: 'both' }); // Or 'forwards'
anim.commitStyles();
anim.cancel();
} I wonder how common this pattern is or if there are similar patterns? |
My understanding was that Adding a flag to |
The spec gives a bit of a summary of the motivation and alternatives here: https://drafts.csswg.org/web-animations-1/#fill-behavior The interesting part with regard to fill modes is that most animation APIs (going back to SMIL upon which CoreAnimation etc. were built) use endpoint exclusive timing so at the exact point when an animation finishes, it has no effect--unless there is an appropriate fill mode set. That's useful for sequencing and repeating animations since it ensures they don't overlap but it's been causing problems for scroll-driven animations recently. (There a bit of explanation in the SMIL spec.) Unfortunately, we very likely can't change this very fundamental part of the model (and other specs like SVG etc. depend on it if we ever want to rebase them on Web Animations). However |
Fwiw, my advice to developers is to avoid filling forwards, as those "stuck" animations tend to catch you out later on, so I see |
I think there are issues with immediately committing the end value when you have composite animations: animA = element.animate(
{transform: ['translateX(0)', 'translateX(500px)']},
{duration: 5000, composite: 'add'});
animA.commitStyles(); // element.style.transform = 'translateX(500px)'; Now the effect is animating from 500px to 1000px? This is why in #5475 I proposed we don't commit immediately but rather commit the style change when the animation finishes (on an infinitely precise timeline which is conceptually identical to filling forwards). |
The proposal here is that for a finished animation you would apply the final value. It wouldn't affect animation's that are not finished. (More precisely, we'd simply opt out of the endpoint exclusive behaviour for the root target effect such that this would still apply to un-finished animations that are in their end delay.) |
The part about jumping to the end is separate (hence why this proposal only addresses half of this issue). |
I started trying to specify how the fill mode part of this works and came across a few possibilities for how this could work. I'll list them out as questions. 1. Does this behavior apply to just the animation on which
|
I strongly agree with all of your suggested answers. I think this is going to be the least surprising and most compatible way to implement it. One thought about point 1 (doesn't affect this proposal), given that commitStyles applies styles at the bottom of the animation stack (i.e. because inline style applies before animation styles), it seems as if commitStyles could only apply the current animation rather than all animations beneath it with the expectation that you would have already had an opportunity to commit the animations below it. This may be less surprising than committing the effect of multiple animations with one call. |
Great, thanks Rob!
Yeah, I'm a little confused about this part. I think the idea was that by compositing the lower animations, the result would be correct even if some of the animations lower in the cascade had not yet been removed but, as you point out, any such animations would clobber the inline style. The WPT for commitStyles includes a few cases where it makes a difference, but I don't know if any of them represent real use cases. |
…commitStyles() behaviour is broken) See: w3c/csswg-drafts#5394
…commitStyles() behaviour is broken) See: w3c/csswg-drafts#5394
I'll check if the proposal is feasible by prototyping it on Gecko :) |
MDN https://developer.mozilla.org/en-US/docs/Web/API/Animation/commitStyles says:
"The commitStyles() method of the Web Animations API's Animation interface commits the end styling state of an animation to the element being animated, even after that animation has been removed. It will cause the end styling state to be written to the element being animated, in the form of properties inside a style attribute."
This is exactly what I want and I like the example in which
commitStyles()
is called right after the animation is created. The expected behavior is very clear since the end state of an animation is well-definedTo my surprise this is not the case in Chrome 84. Looking at the spec it seems MDN got it wrong:
https://drafts.csswg.org/web-animations/#dom-animation-commitstyles says:
"Writes the current effect values produced by this animation’s animation effects to their corresponding effect targets' inline style using the commit computed styles procedure."
So an animation of
transform: translate(100px), duration: 1000
may record a translation of anywhere between 0 and 100px depending on whencommitStyles()
is called. Sure calling it after the animation finishes insures the end state is written but seems to also require settingfill: forwards
. It just seems much easier and more intuitive to have it record a predictable state no matter when it's calledCould
commitStyles()
have an option to always record the end state preferably without involving thefill
property? Even better could it become an animation property and I wouldn't have to usefill
at all?The text was updated successfully, but these errors were encountered: