Framer Motion - scrollYProgress is not updating

513 Views Asked by At

I am using Framer motion + Next.js in my project. i am using Framer motion useScroll hook to track the user's scroll on my page, but it isn't updating. I read framer-motion documentation, and used according to examples they provided. However, I assume i neglacted some stuff. I dont really understand what's wrong with this code. Any help is appriciated.

here is sample code:


const History = () => {
  const targetRef = useRef(null);
  const { scrollYProgress } = useScroll({
    target: targetRef,
  });

  console.log(scrollYProgress);

  const x = useTransform(scrollYProgress, [0, 1], ["1%", "-95%"]);

  return (
    <div>
      <Head>
        <title>매니지온 | History</title>
      </Head>
      <div>
        <h3 className="text-[2.3rem] lg:text-[2.625rem] font-[700] text-center mt-[5rem] w-full tracking-tighter">
          History
        </h3>
        <p className=" text-[1rem] md:text-[1.8rem] lg:text-[2.0625rem] text-[#1f1f1f] mx-auto mt-[1rem] mb-[7rem] xl:mt-[5rem] xl:mb-[9.375rem] ">
          Title Main
          <span
            className="bg bg-no-repeat bg-center  "
            style={{
              backgroundImage: "url(/images/sub/gr-underline02.png)",
              backgroundSize: "100%",
              backgroundPosition: "bottom",
            }}
          >
            Lorem ipsum dolor, sit amet consectetur adipisicing elit. Magnam
            voluptas illo recusandae eaque reiciendis. Illum repellendus harum
            dicta maxime placeat reiciendis. Dolore?
          </span>
          Lorem ipsum dolor sit, amet consectetur adipisicing elit. Voluptate
          facilis officia ut!
        </p>
      </div>
      <div ref={targetRef} className="relative h-[300vh] bg-neutral-900">
        <p className="absolute top-[10%] font-[700] left-6 md:hidden">
          <ArrowBackIcon /> Swipe Left
        </p>
        <div className="sticky top-0 flex h-screen items-center overflow-hidden">
          <motion.div style={{ x }} className="flex gap-4">
            {cards.map((card) => {
              return <Card card={card} key={card.id} />;
            })}
          </motion.div>
        </div>
      </div>
      <div className="h-[10vh] bg-red-500">Footer</div>
    </div>
  );
};

Repo More about can be found here: git-repo

I am trying to use useScroll with useTransform to make horizontally scrollable container: Sample

1

There are 1 best solutions below

0
On

There are two separate issues in your app.

  1. In couple of places you limit height of html, body and root div to 100vh. With these changes, from Framer Motion perspective there is no scroll on your page because whole body fits into viewport. So for it to work you'll need to remove that and make your body scrollable.

  2. In useScroll you need to also specify offset parameter. As per framer motion documentation, this parameter describes how framer motion should track intersection. You need to set it to ["start start", "end end"], this value means that it framer motion will start tracking when start (top side) of viewport intersects with start of your target, at this point scrollYProgress will be 0 and will start increasing as you scroll. end end means that once bottom side of target element and viewport intersect, this will be finish of scroll tracking and scrollYProgress will be 1.

I submitted PR to your repo, you can check it out to see how those changes look in code.