import {useEffect, useState} from 'preact/hooks'; import {JSX, RefObject} from 'preact'; export function useIntersectionObserver({ target, onIntersect, threshold = 0, rootMargin = '0px', enabled = true, }:{ target: RefObject; onIntersect: () => void; threshold?: number; rootMargin?: string; enabled?: boolean; }) { useEffect(() => { if (!enabled) { return; } const observer = new IntersectionObserver(onIntersect, { rootMargin, threshold, }); if (target.current) { observer.observe(target.current); } return () => { if (target.current) { observer.unobserve(target.current); } }; }, [target.current, onIntersect, threshold, rootMargin, enabled]); } export function useRelativeTopOppacity({elem}:{elem: RefObject}) { const [opacity, setOpacity] = useState(1); useIntersectionObserver({ target: elem, threshold: 0, onIntersect: () => { if (elem.current) { addEventListener('scroll', updater); } } }); return opacity; function updater(){ if (elem.current) { const el = elem.current; const rect = el.getBoundingClientRect(); const upIntersect = Math.min(rect.bottom, el.clientHeight) / el.clientHeight; const downIntersect = Math.min(window.innerHeight - rect.top, el.clientHeight) / el.clientHeight; const intersect = Math.min(upIntersect, downIntersect); if (intersect >= 0) { let v = Math.min(Math.max(intersect, 0), 1); //v *= 4/3; v = Math.min(Math.max(v, 0), 1); setOpacity(v); } else{ setOpacity(1); removeEventListener('scroll', updater); } } } }