After reading Framer Motion's documentation, I couldn't find, or maybe I have missed, a possible way to trigger an animation when an element gets into a viewpoint. I've been doing a recommended way to do it, but only with one element. When I add more elements, animations will only trigger after the last element get into a viewpoint, and that shouldn't be like that. The plan is to load every element individually.
So, I've been doing research on a possible way to do it using React Intersection Observer. Unfortunately, I cannot set a valid script that could do the job.
So my goal is to: load every element individually possible using forEach method.
You can check what is happening in the link. You can see the animations under the header load only after the last animate loads.
import React, { useEffect } from "react";
import Button from "../components/Button";
import { motion, useAnimation } from "framer-motion";
import { useInView } from "react-intersection-observer";
import Layout from "../components/Layout";
const easing = [0.6, -0.05, 0.01, 0.99];
const fadeInUp = {
initial: {
y: 60,
opacity: 0
},
animate: {
y: 0,
opacity: 1,
transition: {
duration: 0.6,
ease: easing
}
}
};
const fadeInUp2 = {
initial: {
y: 60,
opacity: 0
},
animate: {
y: 0,
opacity: 1,
transition: {
duration: 0.6,
delay: 0.3,
ease: easing
}
}
};
const fadeInUp3 = {
initial: {
y: 60,
opacity: 0
},
animate: {
y: 0,
opacity: 1,
transition: {
duration: 0.6,
delay: 0.6,
ease: easing
}
}
};
const fadeToRight = {
initial: {
x: -100,
opacity: 0
},
animate: {
x: 0,
opacity: 1,
transition: {
duration: 0.6,
delay: 0.9,
ease: easing
}
}
};
const fadeToLeft = {
initial: {
x: 100,
opacity: 0
},
animate: {
x: 0,
opacity: 1,
transition: {
duration: 0.6,
delay: 0.9,
ease: easing
}
}
};
// const animTitle = {
// initial: {
// y: 100,
// opacity: 0
// },
// animate: {
// y: 0,
// opacity: 1,
// transition: {
// duration: 0.6,
// delay: 1.2,
// ease: easing
// }
// }
// };
const index = () => {
const controls = useAnimation();
const [ref, inView] = useInView();
useEffect(() => {
if (inView) {
controls.start("visible");
}
}, [controls, inView]);
return (
<motion.div exit={{ opacity: 0 }} initial="initial" animate="animate">
<Layout title="Digitalna agencija za sve digitalno ― Digitalko">
<section className="home">
<header>
<div className="title">
<motion.div variants={fadeInUp}>
<h6>
Trenutno traju sniženja od <span>20%</span> popusta
</h6>
</motion.div>
<motion.div variants={fadeInUp2}>
<h1>Digitalna agencija za sve digitalno, doslovno</h1>
</motion.div>
<motion.div variants={fadeInUp3}>
<h2>
We design and build beautiful brands, apps, websites and
videos for startups and tech companies.
</h2>
</motion.div>
<div className="row">
<motion.div variants={fadeToRight}>
<Button url="/test" name="Započni projekt" />
</motion.div>
<motion.div variants={fadeToLeft}>
<Button className="secondary" url="/" name="Naši radovi" />
</motion.div>
</div>
</div>
</header>
<div className="container--services">
<motion.div
ref={ref}
animate={controls}
initial="hidden"
transition={{ duration: 0.6 }}
variants={{
visible: { opacity: 1, y: 0 },
hidden: { opacity: 0, y: 200 }
}}
>
<h1>Našim klijentima pružamo ono što im je najpotrebnije</h1>
</motion.div>
<div className="columnController">
<div className="column">
<motion.div
ref={ref}
animate={controls}
initial="hidden"
transition={{ duration: 0.6, delay: 0.3 }}
variants={{
visible: { opacity: 1, y: 0 },
hidden: { opacity: 0, y: 200 }
}}
>
<p>
We’re a team of designers and developers who spend our time
solving problems and telling the stories of great companies.
We help you think more deeply about what you’re offering
people through your brand, products and services.
</p>
</motion.div>
<br />
<motion.div
ref={ref}
animate={controls}
initial="hidden"
transition={{ duration: 0.6, delay: 0.6 }}
variants={{
visible: { opacity: 1, y: 0 },
hidden: { opacity: 0, y: 200 }
}}
>
<p>
Our mission is to work with companies who want to change the
game. We want to help amazing tech startups get from zero to
one and create beautiful things that make life better.
</p>
</motion.div>
</div>
<div className="column">
<motion.div
ref={ref}
animate={controls}
initial="hidden"
transition={{ duration: 0.6, delay: 0.9 }}
variants={{
visible: { opacity: 1, y: 0 },
hidden: { opacity: 0, y: 200 }
}}
>
<p>
Our mission is to work with companies who want to change the
game. We want to help amazing tech startups get from zero to
one and create beautiful things that make life better.
</p>
</motion.div>
</div>
</div>
<motion.div
ref={ref}
animate={controls}
initial="hidden"
transition={{ duration: 0.6, delay: 0.9 }}
variants={{
visible: { opacity: 1, y: 0 },
hidden: { opacity: 0, y: 200 }
}}
>
<Button url="/test" name="Pogledaj detaljnije" />
</motion.div>
</div>
<div className="container--services">
<motion.div
ref={ref}
animate={controls}
initial="hidden"
transition={{ duration: 0.6 }}
variants={{
visible: { opacity: 1, y: 0 },
hidden: { opacity: 0, y: 200 }
}}
>
<h1>Našim klijentima pružamo ono što im je najpotrebnije</h1>
</motion.div>
</div>
</section>
</Layout>
</motion.div>
);
};
export default index;