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
There are two separate issues in your app.
In couple of places you limit height of
html
,body
and rootdiv
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.In
useScroll
you need to also specifyoffset
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 whenstart
(top side) of viewport intersects withstart
of your target, at this pointscrollYProgress
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 andscrollYProgress
will be 1.I submitted PR to your repo, you can check it out to see how those changes look in code.