WICG / virtual-scroller

Other
2k stars 83 forks source link

Diffable Data Source #166

Closed KevinDoughty closed 5 years ago

KevinDoughty commented 5 years ago

I could've sworn I made this feature request already. I probably called it "fake set animation". It may have been deleted when this was moved from valdrinkoshi/virtual-scroller.

Apple has copied my technique for animation mount/unmount: https://twitter.com/KvnDy/status/742952953556930560

Their version, from WWDC 2019 #220 Advances in UI Data Sources, looks like this: https://twitter.com/KvnDy/status/1137982130812837888

My version is fully "virtualized" but I never made the code public. You can see here, on resize: https://twitter.com/KvnDy/status/775872332028141568

I mentioned in https://github.com/WICG/virtual-scroller/issues/132 how I prefer data source methods, but was told all content is in the DOM. Perhaps if elements are keyed and diffed like React this would work, but data source methods or another technique would still be needed for animation.

As I remember requesting, or maybe it was in react-virtualized or react-window, imperative methods for animating mount/unmount will not be robust enough for heavy insertion and deletion like filtration while typing.

My solution was based on relative animation, which Apple implemented as the default starting in iOS 8 using bug workarounds I provided them. Transitions animate additively from the old value minus the new value to zero, which get added to an underlying value which is instantly set. This was popularized on the web as FLIP.

The discrete version when for example animating from items [A, B, C, D] to [A, B, D] expressed as old minus new becomes [C]. During animation when added to the destination value [A, B, D] it becomes [A, B, D, C] and after sorting remains [A, B, C, D] until the conclusion of the animation, then when removed results in [A, B, D].

When determining which elements are in view, three arrays must be simultaneously walked, the previous state, the current state, and the combined animated state (which may include several states previous, more than just the immediately previous state, along with the current)

Apple's new API may be different, but the underlying concept is remarkably similar, and I suspect there are further similarities in implementation. A problem with their implementation might be how two objects that are equal must have the same hash, but two objects with the same hash are not necessarily equal, and in those cases I suspect their animation would be inconsistent in object order.

My solution places the burden on the developer to provide a sort function, with the caveat that it determine identity, not equality.

The full video, WWDC 2019 #220 Advances in UI Data Sources, is here: https://developer.apple.com/videos/play/wwdc2019/220/

rakina commented 5 years ago

Not sure if I get this right, but you're hoping to have a way to get the set of currently rendered elements in the virtual scroller at some given point in time and then diff the set so that you can animate them? Currently the proposed API have ranges instead of list, as all rendered elements are consecutive. So maybe you can do that manually by saving and comparing the ranges?

KevinDoughty commented 5 years ago

Yes I will try that. I'm closing this issue because it was not well thought out. I will attempt to animate virtual-scroller first, then reopen or open a new issue if and when I can be more specific.