import { useEffect, useRef, useState } from 'react'; interface UseScrollRevealOptions { threshold?: number; rootMargin?: string; triggerOnce?: boolean; } export function useScrollReveal({ threshold = 0.1, rootMargin = '0px', triggerOnce = true, }: UseScrollRevealOptions = {}) { const ref = useRef(null); const [isVisible, setIsVisible] = useState(false); useEffect(() => { const element = ref.current; if (!element) return; const observer = new IntersectionObserver( ([entry]) => { if (entry.isIntersecting) { setIsVisible(true); if (triggerOnce) { observer.unobserve(element); } } else if (!triggerOnce) { setIsVisible(false); } }, { threshold, rootMargin } ); observer.observe(element); return () => observer.disconnect(); }, [threshold, rootMargin, triggerOnce]); return { ref, isVisible }; } interface UseScrollProgressOptions { threshold?: number; } export function useScrollProgress({ threshold = 0 }: UseScrollProgressOptions = {}) { const [progress, setProgress] = useState(0); useEffect(() => { const handleScroll = () => { const scrollTop = window.pageYOffset; const docHeight = document.documentElement.scrollHeight - window.innerHeight; const scrollProgress = scrollTop / docHeight; setProgress(Math.min(1, Math.max(0, scrollProgress))); }; window.addEventListener('scroll', handleScroll, { passive: true }); handleScroll(); return () => window.removeEventListener('scroll', handleScroll); }, []); return progress; } interface UseParallaxOptions { speed?: number; } export function useParallax({ speed = 0.5 }: UseParallaxOptions = {}) { const ref = useRef(null); const [offset, setOffset] = useState(0); useEffect(() => { const handleScroll = () => { if (!ref.current) return; const rect = ref.current.getBoundingClientRect(); const scrolled = window.pageYOffset; const elementTop = rect.top + scrolled; const parallaxOffset = (scrolled - elementTop) * speed; setOffset(parallaxOffset); }; window.addEventListener('scroll', handleScroll, { passive: true }); handleScroll(); return () => window.removeEventListener('scroll', handleScroll); }, [speed]); return { ref, offset }; }