I've been working on an inertial scrolling implementation within Nextjs using Framer Motion but running into a bit of trouble when animation page transitions using animate presence. I'm hooking into the page scroll progress via useScroll
and animating the Y transform with spring physics. The issue, however, is when resetting the window scroll position when navigating between pages. After the component has unmounted, I call window.scrollTo(0,0)
via the AnimatePresence
onExitComplete
callback, but because I'm transforming the page position via spring physics, the scroll reset doesn't complete immediately. So when new pages are mounted, the page transform to reset the scroll is still running.
Additionally, I've included scroll={false}
in my Next Link
components to prevent the default scroll to top functionality so I can handle this manually via the AnimatePresence
component as mentioned above. But this doesn't seem to be working.
There's a bit of code involved so I created a minimal reproduction repo here.
I also notice that passing scrollY
to the y property of the variant object prevents the unwanted scrolling behavior on page transition. But passing something like scrollY - 128
breaks the behavior:
const variants = {
hidden: { opacity: 0, x: 0, y: 64 },
enter: { opacity: 1, x: 0, y: 0 },
exit: { opacity: 0, x: 0, y: scrollY },
};
y value in exit variant wasn't being updated to match latest scrollY value. Solution:
useEffect(() => {
return scrollY.onChange((latest) => {
variants.exit.y = -scrollY.current - 128;
});
});