Open bhollis opened 2 years ago
Does this persist if you convert the overflow: scroll
to a motion.div
and add the layoutScroll
prop?
Hi, i have same issue here.
I have tried @mattgperry suggestion to change overflow: scroll
to layoutScroll
but it's still occured. On my app, this bug only occur if i remove the middle of item, so if i remove first and last item it will be fine. Then, i try to inspect what happen on the css, i found the transform
is not going back to none
.
Hope this help.
layoutScroll
does seem to fix it in my sandbox. I hadn't seen that property before :-D. I'll apply it in my full app and see if it helps.
any update on how to fix this?
layoutScroll
doesn't fix the issue for me.
converting the container to motion.div
and add overflow: scroll
with layoutScroll
prop fix it for me too
i think you should use usePresence
hook, and call safeToRemove
function which is returned with isPresent
which indicated the presence of element as boolean (doc: https://www.framer.com/docs/animate-presence/#usepresence)
i am not sure will this work in your case or no, i wish it help you.
None of these worked for me:
Screencast from 11-14-2023 11:12:09 AM.webm
Screencast from 11-14-2023 11:13:57 AM.webm
"use client";
import { motion, useScroll } from "framer-motion";
import { useEffect, useRef } from "react";
const Card = () => {
const containerRef = useRef(null);
const { scrollYProgress } = useScroll({
target: containerRef,
offset: ["0 1", "1.33 1"],
});
useEffect(() => {
console.log(scrollYProgress);
}, [scrollYProgress.get()]);
return (
<motion.div
ref={containerRef}
layout
style={{
scale: scrollYProgress,
// opacity: scrollYProgress,
}}>
<div className="flex items-center justify-center p-20 w-full bg-slate-500">
AAA
</div>
</motion.div>
);
};
////////////////////////////////////////////////////////////////////////////////
export default function Home() {
const ref = useRef(null);
const { scrollYProgress } = useScroll({ container: ref });
return (
<div dir={"ltr"}>
<svg id="progress" width="100" height="100" viewBox="0 0 100 100">
<circle cx="50" cy="50" r="30" pathLength="1" className="bg" />
<motion.circle
cx="50"
cy="50"
r="30"
pathLength="1"
className="indicator"
style={{ pathLength: scrollYProgress }}
/>
</svg>
<motion.ul layoutScroll={true} style={{ overflow: "scroll" }} ref={ref}>
<Card />
<Card />
<Card />
<Card />
<Card />
<Card />
<Card />
<Card />
<Card />
<Card />
</motion.ul>
</div>
);
}
it seems elements are still taking the screen as their container at the initial phase (Since the fifth element scale corresponds to what it should be with the screen as its container).
1. Describe the bug
I have a scrollable div, within which I have a list of
motion.div
s. These useAnimatePresence
to animate themselves away, and each haslayout
set so the remaining items will animate to fill the hole left by that item.When the div is scrolled, removing an item results in incomplete transitions and overlapping items, or other items above the removed items will move down, e.g.:
3. IMPORTANT: Provide a CodeSandbox reproduction of the bug
https://codesandbox.io/s/framer-motion-layout-animation-bug-when-scrolled-pot7y3?file=/src/styles.css
4. Steps to reproduce
Sometimes, they will overlap or leave a gap. This minimal repro renders lighter-weight components than my real app, so it can be a bit harder to see it mess up - try scrolling with a trackpad and clicking before the scroll fully settles (though in my full application, this happens reliably even when scrolling has settled).
5. Expected behavior
I expect the item that's clicked to animate out, and the remaining items to animate into their place in the list.
6. Video or screenshots
https://user-images.githubusercontent.com/313208/156072905-5884d634-02aa-40e2-b1a3-2c7cc49e9712.mov
7. Environment details
Chrome 98 on an M1Max MacBook Pro.