Nooblantis District
Nooblantis District

Reputation: 141

How to use Variants with Framer Motion useAnimation

I need my animation to show when it reaches viewport with this logic below from stack overflow:

import { useInView } from "react-intersection-observer";
import { motion, useAnimation } from "framer-motion";

const Component = () => {
    const animation = useAnimation();    
    const [ref, inView, entry] = useInView({ threshold: 0.1 });

    useEffect(() => {
      if (inView) {
        animation.start("visible");
      } else {
        animation.start("hidden");
      }
    }, [animation, inView]);

    const variants = {
        visible: {
          y: 0,
          opacity: 1,
          transition: { duration: 0.5, delayChilden: 0.2, staggerChildren: 0.1 },
        },
        hidden: {
          y: enter,
          opacity: 0,
        },
    }
    return (
<>
        <motion.div
          ref={ref}
          animate={animation}
          initial="hidden"
          variants={{variants}}>TITLE 1</motion.div>
//---------CONTENTS HERE
        <motion.div
          ref={ref}
          animate={animation}
          initial="hidden"
          variants={{variants}}>TITLE 2</motion.div>
//---------CONTENTS HERE
       <motion.div
        ref={ref}
        animate={animation}
        initial="hidden"
        variants={{variants}}>TITLE 3</motion.div>
</>
      );
}

But using variants to reuse animation for different headings, the animation loads no longer until I reach the last heading of the page

I thought of having different variants for each title but that would just make my code messy. How do I sort this out?

Upvotes: 0

Views: 4000

Answers (1)

Nooblantis District
Nooblantis District

Reputation: 141

So I figured out the way to do this, all you have to do is have as many useAnimation and inView needed for the number of elements you are going to apply In my case, that's 3 useAnimation & inView for 3 titles

const title1 = useAnimation()
  const title2 = useAnimation()
  const title3 = useAnimation()

  const [ref, inView, entry] = useInView({ threshold: 0.5 });
  const [ref1, inView2] = useInView({ threshold: 0.5 });
useEffect(() => {
    if (inView) {
      animation.start("visible")
    } else {
      animation.start("hidden");
    }

    if (inView2) {
      animation2.start("visible")
    } else {
      animation2.start("hidden");
    }
  }, [inView, inView2]);

Voila

Upvotes: 0

Related Questions