useInViewport
loomui/use-in-viewportFreeUtility
Tells a component whether it is on screen, so a looping animation can stop while nobody is watching it.
Install it
npx shadcn@latest add https://loomui.design/r/use-in-viewport.jsonSource
1"use client"23import * as React from "react"45/**6 * Whether the element is on screen. A looping animation that nobody can see is7 * work the browser does for nothing: CSS animations keep ticking while they are8 * scrolled away, and the compositor keeps the layers alive to do it.9 *10 * Starts `true` so the first paint is never a paused one, on the server or11 * where `IntersectionObserver` is missing.12 */13export function useInViewport<T extends Element>(14 ref: React.RefObject<T | null>,15 /** Grown by this much, so a loop is already running as it scrolls in. */16 margin = "200px"17) {18 const [visible, setVisible] = React.useState(true)1920 React.useEffect(() => {21 const node = ref.current22 if (!node || typeof IntersectionObserver === "undefined") return2324 const observer = new IntersectionObserver(25 ([entry]) => setVisible(entry.isIntersecting),26 { rootMargin: margin }27 )2829 observer.observe(node)30 return () => observer.disconnect()31 }, [ref, margin])3233 return visible34}
