framer / motion

Open source, production-ready animation and gesture library for React
https://framer.com/motion
MIT License
22.27k stars 733 forks source link

Fix projection of fixed elements when scrolling #2647

Open koop opened 2 weeks ago

koop commented 2 weeks ago

Fixes the failing position: fixed; projection tests added in #1768.

Fixes issues #2514, #2006, and #1972.

Before After
Sandbox to reproduce the issue Sandbox to verify fix (with patch applied)
2024-05-02 13 37 24 2024-05-02 13 38 16

Details

To handle projecting fixed elements within scrollable pages: as I understand it, the existing logic accounted for scroll root ancestors within removeElementScroll by iterating over the path, but this didn't account for the case where the current element was a fixed element, because the path does not contain the current node. Instead, we now avoid adding the scroll position in measurePageBox when the projection is or is within a fixed element.

To handle projected fixed elements within scrollable elements: this was a similar case where we weren't accounting for the current element's scroll information. If the current element is fixed, we can return early from removeElementScroll.

To handle projecting when an element changes between fixed and static positions: we track whether the position was fixed during the snapshot phase (instead of relying on the most recently measured value) and use that to determine whether the projection considers an element fixed or not. Two considerations here:

mattgperry commented 1 week ago

Hey this is really cool, thanks for the PR! I have some stuff to deal with first around getting deferred keyframes into Framer but will check it out after.

We don't need to worry so much about position: sticky - stickied elements themselves can flick between "fixed" and "static" modes and there's no good way of tracking this. But I'll probably double check we have the tests to check for regressions still.

koop commented 1 week ago

Sounds good!

We don't need to worry so much about position: sticky - stickied elements themselves can flick between "fixed" and "static" modes and there's no good way of tracking this.

That's roughly what I expected (and why I didn't include it here), monitoring sticky position/state is a pain.

lilingxi01 commented 6 days ago

Thank you for making this PR! This could resolve a lot of transition glitches related to position: fixed.