I'm using framer-motion to animate multiple elements in one page. Since framer-motion doesn't have an easy way of animating an element once it's in viewport I'm using this method:
const controls = useAnimation();
const { ref, inView } = useInView();
useEffect(() => {
if (inView) {
controls.start("visible");
}
if (!inView) {
controls.start("hidden");
}
}, [controls, inView]);
const fadeFromBottom = {
hidden: {
opacity: 0,
y: -5,
},
visible: {
opacity: 1,
y: 0,
transition: {
type: "spring",
delay: 0.4,
},
},
};
return (
<motion.section
ref={ref}
variants={fadeFromBottom}
initial='hidden'
animate={controls}
>
<img src={image} alt='image'>
</motion.section>
However, this method is only allowing me to animate one element per .jsx file. If I wanted to animate two sections with different animations when they enter the viewport, how do I do that? For example how would I animate these two sections at different times with different animations?
<motion.section
ref={ref}
variants={fadeFromBottom}
initial='hidden'
animate={controls}
>
<img src={image} alt='image'>
</motion.section>
<motion.section
ref={ref}
variants={fadeFromLeft}
initial='hidden'
animate={controls}
>
<img src={image} alt='image'>
</motion.section>
You can create a hook that wraps the logic of animating components on "in view"
The use the hook for all things you want to animate
and then hook up the refs to the related dom elements.
you could also just duplicate the existing use of
useInView
hook and add some logic to the useEffect. I think this hook cleans it up a bit though.