useVisible() Hook
Intersection Observer simplified
The useVisible() hook allows you to easily determine if a referenced DOM element is within the viewport. This is particularly useful for triggering animations or actions when the user scrolls to a specific section of the page. It returns a boolean indicating the visibility of the element.
useVisible.tsx
import { useState, useEffect, RefObject } from 'react' export const useElementVisibility = (elementRef: RefObject<Element>): boolean => { const [isVisible, setIsVisible] = useState(false); useEffect(() => { const targetElement = elementRef.current; // Function to monitor visibility changes const onVisibilityChange = (entries: IntersectionObserverEntry[]) => { const [entry] = entries; setIsVisible(entry.isIntersecting); }; // Initialize Intersection Observer to watch visibility changes if target exists if (targetElement) { const visibilityObserver = new IntersectionObserver(onVisibilityChange, { root: null, // viewport is the observational reference rootMargin: '0px 0px 600px 0px', // margins around the root threshold: 0.01, // minimum portion of the target visible for callback }); visibilityObserver.observe(targetElement); // Cleanup by disconnecting observer when component is unmounted return () => visibilityObserver.disconnect(); } }, [elementRef]); // Effect dependencies return isVisible; };
Example Usage
As a user scrolls through a web page, the FadeInComponent transitions from being transparent to fully visible, creating a smooth fade-in effect. it's a simple example of how the useVisible() hook can be used to trigger animations based on the visibility of an element.
FadeInComponent.tsx
import React, { useRef } from 'react'; import { useVisible } from '@/hooks/useVisible'; const FadeInComponent = () => { const ref = useRef(null); // Create a ref for the component we want to observe. const isVisible = useVisible(ref); // Use the hook to check visibility. return ( <div ref={ref} className={`bg-light-blue-500 h-72 w-full transition-opacity duration-1000 ease-in-out ${ isVisible ? 'opacity-100' : 'opacity-0' }`} > <p className="pt-32 text-center text-white"> {isVisible ? '🎉 I am now visible!' : 'Scroll down to see me appear!'} </p> </div> ); }; export default FadeInComponent;