Adam
Adam

Reputation: 1242

Framer Motion Page Transition Next JS Router.push

I made the following using the nextjs and framer motion

I have a list of images that I'm mapping over and assigning them a layoutid and an optional variant to animate. The layoutid corresponds to the layoutid on the model1, model2, model3 pages.

Current Behaviour

When first going to the home page and clicking on an image I update some state and set the variant animation to false, this then tells that image to use the layoutid, it then fades out the other images and animates the clicked image into place on the component that is loaded (model1, model2, model3)...Great it works!

If you then click home in the navigation and try clicking an item again it doesn't work, all images are faded out and the clicked image doesn't animated.

Click refresh on the homepage and it works as desired!

here is the code for the page, I suspect it could be something to do with the routing or settings in _app.js

export default function Home() {
const router = useRouter();
const [isClicked, setIsClicked] = useState(null);

const onHandlerClick = (item, href, e) => {
    e.preventDefault();
    setIsClicked(item);
    router.push(href, { scroll: false });
};

return (
    <div className="l-grid l-grid-outter">
        <div className="c-home-maincontent">
            <div>
                <main>
                    <motion.div className="l-grid-3-col" initial="initial" animate="enter" exit="exit" variants={{ exit: { transition: { staggerChildren: 0.1 } } }}>
                        {images.map((item, index) => {
                            return (
                                <motion.div
                                    key={index}
                                    className="c-home-overflowimage c-home-overflowimage2"
                                    layoutId={`imageAnimation${item}`}
                                    variants={isClicked === item ? false : postVariants}
                                    transition={{ ...transition }}
                                >
                                    <a href={`/model${item}`} onClick={(event) => onHandlerClick(item, `/model${item}`, event)}>
                                        <motion.img
                                            src="/yasmeen.webp"
                                            whileHover={{
                                                scale: 1.1,
                                            }}
                                        />
                                    </a>
                                </motion.div>
                            );
                        })}
                    </motion.div>
                </main>
            </div>
        </div>
        <Footer />
    </div>
);
}
function MyApp({ Component, pageProps }) {
const router = useRouter();

return (
    <>
        <DefaultSeo {...Seo} />
        <AnimateSharedLayout type="crossfade">
            <AnimatePresence exitBeforeEnter initial={false}>
                <Component {...pageProps} key={router.asPath} />
            </AnimatePresence>
        </AnimateSharedLayout>
    </>
);
}

export default MyApp;

Upvotes: 2

Views: 1466

Answers (1)

Adam
Adam

Reputation: 1242

Updated the code to include an animate set to false if its the clicked item

<motion.div className="l-grid-3-col" initial="initial" animate="enter" exit="exit">
    {images.map((item, index) => {
        return (
            <motion.div
                key={index}
                className="c-home-overflowimage c-home-overflowimage2"
                layoutId={`imageAnimation${item}`}
                animate={isClicked === item ? false : true}
                variants={isClicked === item ? false : postVariants}
                transition={{ ...transition }}
            >
                <a href={`/model${item}`} onClick={(event) => onHandlerClick(item, `/model${item}`, event)}>
                    <motion.img
                        src="/yasmeen.webp"
                        whileHover={{
                            scale: 1.1,
                        }}
                    />
                </a>
            </motion.div>
        );
    })}
</motion.div>

Upvotes: 1

Related Questions