-
Notifications
You must be signed in to change notification settings - Fork 711
[CSS-View-Transitions-2] Relative Additive Animation #9578
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
It works just fine even when changing element order. There may be some additional time complexity in the union and difference operations, and there may be some stacking order surprises when one element appears in front of another suddenly, but it works just fine. |
There is no time complexity issue. Converting from an array to a set, testing membership, then converting back to an array is O(3n) which is still linear. There are no leaks, that’s the point of animating to zero. When finished memory can be freed without using a fill mode. What remains to be solved appear to be trivialities. What gets passed to the sort function? Are they elements, IDs, data attributes, or something else? I guess there should be a different sort function per pseudo element for SPAs, but I haven’t looked at that in detail. I’m sorry that I was the one to solve this as the bias seems to be against me and not the proposed algorithm, but there is no other solution except not allowing View Transitions to handle interruption at all, which is inferior and embarassingly backwards looking. |
Animations will need to be automatically copied from those pseudo elements back to their originals for re-entry, which I failed to mention. A web developer can acheive subgroup animation by manually copying those animations to sub-elements, which might be tricky for anything other than translation and opacity. If the sort function is absent, automatic copying animations from the pseudo back to the original element should not happen. Square brackets denote groups and subgroups. [ A | B[1,2,3] | C ] # original I wrote to the public-fx mailing list about animation copying. With the help of one W3C member I was able to reproduce an example I wrote in Obj-C. This was needed for sub-dividing glyph runs in NSTextView, which were drawn on GPU textures and shuffled around with Core Animation. Sadly all those javascript animation examples broke when the entire web-animations js shim repository was deleted and additive animation was removed from its replacement. This was the animation copying example in Obj-C: It’s been over a decade now. |
There would be two sort functions in the above example, using "A, B, C" and "1, 2, 3" each for their own separate group. Sort functions must be able to sort all possible combinations of subviews. If the web developer changes the function output midway somehow, behavior is undefined, or perhaps better stated, “hilarity will ensue”. |
I could not have come up with the ergonomics of the View Transitions API for lack of experience. I do have experience with shuffling around GPU textures. It takes: Relative additive animation and a sort function as single source of truth. The absence of the optional sort function second parameter to startViewTransition allows for existing behavior, its inclusion allows for so much more. |
One more thing, from the list of steps to achieve subgroup animation, steps three and four. The re-entry and re-exit animations must happen simultaneously. Equal and opposite additive animations would cancel each other out. The result would be only the original exit animation having any visual effect on sub-elements 1 and 3, while sub-element 2 would animate back in. |
TL;DR: Instead of animating a sub element back in you must simultaneously animate the outer element back in and the other sub elements back out. This may not be the exact same thing, but you can really build a lot with this pattern. |
I’ve got it. For the sort function, zero establishes identity, not equality. Unless it’s a sub-element that is also meant to be in one of these groups. So you scan down to the next group, however deeply nested it is. If an element does not belong to a group and is not handled by the sort function, or any beneath it, it returns null. |
Sort function returns zero for identity, or if it's a descendent element from another group. Sort functions return null if not handled. |
That means any sort function will have to be able to sort all possible elements in its group, but also all possible elements of any subgroups, no matter how deeply nested. Zero establishes identity or descendant membership. If there are any subgroups, they must return null for any non-members. It's a little hairy but I think it would work. |
Sort function. For sub-elements not handled at the current level, return null instead of 1, 0, or -1. That means a different invocation of startViewTransition, with a corresponding different pseudo-element, has provided the sort for the sub-element. To animate back in a sub-element of an element being animated out, a rasterized representation of the group would have to be redrawn with the sub-element removed from the picture. That group would have to be kept in memory, just inaccessible to the page author, for the duration of the exit animation. Styles would have to be preserved too. I hope those are what are called "snapshots" in Firefox/Servo, and they're not rasterized images. Styles of these snapshots would not have to be recalculated but the sub-element’s snapshot would have to be removed. Yes it’s hairy. Exit animations on the group would have to be copied from the group to the newly reinserted sub-element. A fade out animation continues to run, and a new fade in animation runs additively on top. Also, elements animating in should be live and instantly accessible to events. If discrete-state were implemented, hit testing would always resolve to destination values regardless of animation state. No blocking the UI please. |
Step one is |
Very sorry, this is not feasible for scenarios where items are deleted. The sort requirement would ultimately rely on completion handlers to be effective. It pains me to say this, I had really hoped otherwise. Even if sort indices spanned the max and lowest float values and new inserts used a halfway value, eventually those indices would need to be balanced like a binary tree. I can’t ask for this to be standardized. Animating display from block to none is an easier solution to the equivalent problem. |
A sort function would still work for filtering, or deletion if items can’t themselves be re-ordered and can only be appended when adding, by using sequential keys, or if the page author doesn’t mind a small memory leak in a map that continuously grows. These are the use cases where retargeting VIew Transitions would be possible. |
Also, a sort function would be possible if the page author could update state in an animation completion handler, but the whole point of “Discrete Set” animation was to avoid that. Might still be something the W3C would be interested in. |
I’m not too familiar with what you’re doing, in particular MPA vs. SPA. I only know that I solved something very similar and it might fit into your API. I call it relative additive animation.
I propose you implement
CompositeOperation: blend
andanimation-composition: blend
from:https://phabricator.services.mozilla.com/D156634#5139009
You might as well implement
transition-composition: blend
as it is better than CSS Transitions’ Faster Reversal but is not needed for View Transitions. The fourth from the above list is unnecessary. The fifth is unfinished and experimental, and could possibly provide a moderate performance increase for compositor animations but is also not needed for View Transitions.I propose you implement a new animation primitive, a discrete form of relative additive animation for collections. If you want to expose it to javascript arrays or NodeList that would be great too but might not be necessary for View Transitions.
The
relative
in relative additive animation refers to conversion of values by subtracting the new value from the old, old minus new, and using that as the start value, and animating to zero. This was popularized on the web as FLIP, but the W3C has so far ignored its benefits when additive.Old minus new of a discrete collection when animating from [ A, B, C, D ] to [ A, B, D ] is simply [ C ], the item being removed. The animations are additive which results in [ A, B, D, C ]. They are not in the correct order, which requires sorting to return to [ A, B, C, D ] for the duration of the exit animation.
I propose View Transitions accept an optional second parameter sort function for
startViewTransition
. This sort function must sort all possible combinations of elements, where returning 0 would not establish equality, but instead identity.Considering how transitioning elements are moved to an overlay pseudo element, the above discrete animation would resemble something more like [ A, B, D ] + { C } where the curly braces are the pseudo element. If [ B ] were removed before the previous transition finished, that would result in something like [ A, D ] + { B, C }.
The CSS Values spec might also need to define subtraction but I’m not sure. This is more than just addition * -1.
Related:
#8678
#9512
The text was updated successfully, but these errors were encountered: