next.jssmooth-scrollingframer-motionpage-transition

Nextjs x Framer Motion inertial scrolling with page transition


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 },
  };

Solution

  • 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;
        });
      });