View code
HTML:
<img data-animate="bottom" src="https://picsum.photos/600/400?random=1" alt="Random 1" />
<img data-animate="top" src="https://picsum.photos/600/400?random=2" alt="Random 2" />
<img data-animate="left" src="https://picsum.photos/600/400?random=3" alt="Random 3" />
<img data-animate="bottom" src="https://picsum.photos/600/400?random=4" alt="Random 4" />
JS:
/* Intersection observer */
const animateWrapper = useRef(null)
useEffect(() => {
if (!animateWrapper.current) return
const animateContainers = animateWrapper.current.querySelectorAll('[data-animate]')
animateContainers.forEach(container => {
const observer = new IntersectionObserver(
elements => {
elements.forEach(el => {
if (el.isIntersecting) {
// Do stuff here when element is intersecting
el.target.classList.add('animate')
}
})
},
{
// Options
threshold: 0.5,
},
)
// Initiate observation
const observeTimeout = setTimeout(() => {
observer.observe(container)
}, 500)
return () => {
clearTimeout(observeTimeout)
observer.unobserve(container)
}
})
}, [animateWrapper])
CSS:
[data-animate] {
opacity: 0;
}
[data-animate="bottom"].animate {
animation: 1s slideInFromBottom forwards;
}
[data-animate="right"].animate {
animation: 1s slideInFromRight forwards;
}
[data-animate="left"].animate {
animation: 1s slideInFromLeft forwards;
}
[data-animate="top"].animate {
animation: 1s slideInFromTop forwards;
}
@keyframes slideInFromBottom {
from {
opacity: 0;
transform: translateY(100px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes slideInFromTop {
from {
opacity: 0;
transform: translateY(-100px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes slideInFromRight {
from {
opacity: 0;
transform: translateX(100px);
}
to {
opacity: 1;
transform: translateX(0);
}
}
@keyframes slideInFromLeft {
from {
opacity: 0;
transform: translateX(-100px);
}
to {
opacity: 1;
transform: translateX(0);
}
}