portfolio-page/src/hooks/useScrollReveal.ts

40 lines
1.0 KiB
TypeScript

import { useEffect, useRef } from 'react';
/**
* Observes all `.reveal-item` descendants of the returned ref and adds
* `.is-visible` when they enter the viewport, triggering the CSS transition
* defined in globals.scss.
*
* The observer starts immediately so that elements already in the viewport
* become visible right away — including after language-change remounts.
*/
export function useScrollReveal() {
const ref = useRef<HTMLElement>(null);
useEffect(() => {
const container = ref.current;
if (!container) return;
const observer = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
entry.target.classList.add('is-visible');
observer.unobserve(entry.target);
}
});
},
{ threshold: 0.12 }
);
const items = container.querySelectorAll('.reveal-item');
items.forEach((el) => observer.observe(el));
return () => {
observer.disconnect();
};
}, []);
return ref;
}