import React from 'react';
import { useInView } from 'react-intersection-observer';
const Component = () => {
//ref pass in element inView is true when we move to ref part in webpage
const { ref, inView, entry } = useInView({
/* Optional options */
threshold: 0,
});
return (
<div ref={ref}>
<h2>{`Header inside viewport ${inView}.`}</h2>
</div>
);
};
npm i react-intersection-observer
Start by installing react intersection observer
//npm i react-intersection-observer
import React, { useEffect } from "react";
import { useInView } from "react-intersection-observer"; //import {useInView} tells the dom when something is in viewport
import { motion, useAnimation } from "framer-motion"; //import {motion,useAnimation}
//I'm assuming you already know how to work with variants in framer motion
//create a variant for your animation
const nameVariant = {
visible: { x: 50, y: 150, transition: { delay: 5, duration: 2 } },
hidden: { x: 450, y: 250 },
};
const YOURCOMPONENT = () => {
const control = useAnimation();
const [ref, inView] = useInView();
useEffect(() => {
if (inView) {
control.start("visible"); //when in view,start the visible animation variant
} else {
control.start("hidden"); //else its hidden
}
}, [control, inView]);
return (
<motion.div
ref={ref} //pass the ref to tell rio what is being checked
variants={nameVariant} //pass in your variant
initial="hidden" //pass initial values
animate={control} //pass in control as it will be animated when element is in view
className="title w-full relative flex">
<h1>Hello my friend</h1>
</motion.div>
)
}
yarn add react-intersection-observer
<script>
import { onMount } from 'svelte'
let isVisible = false;
let element;
const handleIntersect = (e, observer) => {
e.forEach(entry => {
isVisible = entry.isIntersecting;
if (entry.isIntersecting) {
observer.unobserve(entry.target);
}
})
}
onMount(() => {
const root = null;
const rootMargin = '0px 0px -100px 0px';
const options = { root, rootMargin };
const observer = new IntersectionObserver(handleIntersect, options);
observer.observe(element);
})
</script>
<div
bind:this={element}
class:visible={isVisible}
>
<slot {isVisible} />
</div>
<style>
div {
opacity: 0;
transform: translateY(100px);
transition: all 1s ease-in-out;
}
div.visible {
opacity: 1;
transform: translateY(0)
}
</style>