Stagger divswhen they are in view using react-intersection-observer and framer-motion

381 Views Asked by At

I'm working on a React app and I want to add some animations using react-intersection-observer and framer-motion.

CodeSandbox

So far, everything is working correctly. All my divs are animating when they are in view.

But I want to add staggering to these div boxes. I want the h1 from the black box to fade in, then the h1 from the gray box, the h1 from black box again, then h1 from the gray one etc. As you scroll, I want the same staggering effect.

I tried using staggerChildren, but with no real success.

import "./styles.scss";
import { motion, useAnimation } from "framer-motion";
import { useInView } from "react-intersection-observer";
import { useEffect } from "react";

const boxItems = [
  {
    id: 1,
    title: "box-1"
  },
  {
    id: 2,
    title: "box-2"
  }
];

function FadeInWhenVisible({ children }) {
  const controls = useAnimation();
  const [ref, inView] = useInView();

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

  return (
    <motion.div
      className="container-inner"
      ref={ref}
      animate={controls}
      initial="hidden"
      transition={{ duration: 1.2 }}
      variants={{
        visible: { y: 0, opacity: 1 },
        hidden: { y: 5, opacity: 0 }
      }}
    >
      {children}
    </motion.div>
  );
}

function App() {
  return (
    <div className="App">
      <div className="container">
        <FadeInWhenVisible>
          {boxItems.map((item) => (
            <div key={item.id} className="box">
              <h1>{item.title}</h1>
            </div>
          ))}
        </FadeInWhenVisible>
        <FadeInWhenVisible>
          {boxItems.map((item) => (
            <div key={item.id} className="box">
              <h1>{item.title}</h1>
            </div>
          ))}
        </FadeInWhenVisible>
        <FadeInWhenVisible>
          {boxItems.map((item) => (
            <div key={item.id} className="box">
              <h1>{item.title}</h1>
            </div>
          ))}
        </FadeInWhenVisible>
        <FadeInWhenVisible>
          {boxItems.map((item) => (
            <div key={item.id} className="box">
              <h1>{item.title}</h1>
            </div>
          ))}
        </FadeInWhenVisible>
      </div>
    </div>
  );
}

export default App;
0

There are 0 best solutions below