-
Notifications
You must be signed in to change notification settings - Fork 711
[web-animations] Allow adjacent filling animations to be coalesced #3210
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
Analysis of the problemIssue 1: Specified values can depend on contextAnimations can be defined with property values such as Consider an animation that moves an element to When several animations affecting the same property of the same element have finished and are filling, the final animated value of the property might be the combination of a number of such context-sensitive values (e.g. Furthermore, this problem does not merely apply to additive animations (i.e. animations with composite operations elem.animate({ left: '5em' }, { duration: 1000, iterations: 0.5, fill: 'forwards' });
elem.animate({ left: '50vw' }, { duration: 1000, fill: 'forwards' }); In the above example the fill result will be Issue 2: Operations cannot be re-ordered to create an intermediate result independent of the underlying valueTo calculate the animated value of a property, a stack of animation effects is generated. In order to address the memory leak identified in this issue we would like to coalesce adjacent filling effects within this stack. Even supposing issue 1 can be resolved such that we do not need to maintain the specified values of such effects, we face another problem: we cannot always calculate the result of an effect independent of its underlying value. As a result, we cannot coalesce effects. In general, the result of a filling keyframe effect for a single property is as follows:
where:
In order to be able to calculate this result independent of For example, if we could somehow re-write the above along the lines of:
(where ∅ represents a no-op/neutral value as described in #2204) we could most likely represent a section of the stack as a component that is independent of the underlying value (the For many properties this is possible. For example, since lengths are combined using addition and multiplication, we can trivially factor out the underlying component and add it later. However, consider transform lists. Interpolation and accumulation produce different results based on the shape of the inputs and are therefore not only not commutative (neither is addition) but nor are they associative. For example, suppose we have an animation that fills forwards at the midpoint of an interval between ‘rotate(30deg)’ and ‘rotate(390deg)’. Furthermore, suppose both values have composite operation ‘accumulate’. The animated fill value is calculated as:
Now suppose If we try to factor out a component that is independent of the underlying value (e.g. by substituting 'none' for You can observe the difference in output here: https://codepen.io/birtles/pen/GYWxww Because we have interpolation and accumulation procedures that are not associative it seems we cannot collapse the adjacent filling animations in the general case without altering the output. |
Proposed solutionFirst a few prerequisites:
And a few observations:
I've discussed this with @heycam a little and while I still don't have any really good solutions, my current thinking is:
As an example, for a transform list value, the fill-able value would be the matrix form of the value. This would only apply for keyframes with a composite mode of 'add' or 'accumulate' (so that most common use cases still work as expected) and the conversion would happen on setting so there is no change in behavior between running and filling. This conversion should ensure we have means of representing a adjacent filling effects that is independent of context and the underlying value. Calculating this value will likely require the use of the neutral / no-op value concept. I've tried and abandoned a number of other approaches and this is the best I have so far. It's not ideal in that it means you basically can't use |
One further issue to clarify is that there is currently discussion of making interpolation dependent on context with regards to |
In light of the requirement to freeze interpolation context, I'm starting to consider converting these additive keyframes at the point when the animation begins filling indefinitely. It would mean a jump in behavior but not a jump in output and I wonder if it might be more natural for an author to understand ("Oh, that animation's not updating because it's finished"). SMIL takes this to the extreme where, per spec, a frozen to-animation doesn't even respond to the base value anymore. At least in Gecko we chose to deviate from the spec here and make it responsive. |
I've updated the patch for this so that it should be mostly complete now. |
Closed by db06d5f. |
Closely related:
getAnimations()
([web-animations-1] Define requirements for retaining animations to be returned by getAnimations #2054)Using the Web Animations API authors can easily generate animations in an unbounded fashion. Unless a means is provided to UAs to discard or compact these animations, this will result in a memory leak.
For example:
Comparing to other animation techniques:
<animate>
-type element only has one active interval at a time so that number of simultaneous animations is bounded by the number of<animate>
-type elements (and if an author is producing<animate>
elements in an unbounded fashion they hopefully won't be surprised to learn that they're leaking memory!).One reason past animations must be retained is due to the way the
getAnimations()
API is currently defined. Issue #2054 will define a means to avoid havinggetAnimations()
return all such animations.The other reason past animations must be retained is to produce the correct result when additive animations or animations with implicit keyframes are involved. As a result, even once
getAnimations()
is fixed, there are many circumstances where UAs cannot discard or compact past animations, thereby producing a memory leak.The text was updated successfully, but these errors were encountered: