51 lines
1.4 KiB
TypeScript
51 lines
1.4 KiB
TypeScript
"use client"
|
|
|
|
import { useEffect } from "react"
|
|
import { usePathname } from "next/navigation"
|
|
|
|
export default function RevealObserver() {
|
|
const pathname = usePathname()
|
|
|
|
useEffect(() => {
|
|
let observer: IntersectionObserver | null = null
|
|
const raf = requestAnimationFrame(() => {
|
|
const allDataWid = document.querySelectorAll<HTMLElement>("[data-w-id]")
|
|
const targets: HTMLElement[] = []
|
|
|
|
allDataWid.forEach((el) => {
|
|
if (el.style.opacity === "0" && el.style.filter?.includes("blur")) {
|
|
el.style.transform = "translateY(24px)"
|
|
el.style.transition = "opacity 0.7s ease-out, filter 0.7s ease-out, transform 0.7s ease-out"
|
|
targets.push(el)
|
|
}
|
|
})
|
|
|
|
if (!targets.length) return
|
|
|
|
observer = new IntersectionObserver(
|
|
(entries) => {
|
|
entries.forEach((entry) => {
|
|
if (entry.isIntersecting) {
|
|
const el = entry.target as HTMLElement
|
|
el.style.opacity = "1"
|
|
el.style.filter = "blur(0px)"
|
|
el.style.transform = "translateY(0)"
|
|
observer?.unobserve(el)
|
|
}
|
|
})
|
|
},
|
|
{ threshold: 0.05, rootMargin: "0px 0px -5% 0px" },
|
|
)
|
|
|
|
targets.forEach((el) => observer!.observe(el))
|
|
})
|
|
|
|
return () => {
|
|
cancelAnimationFrame(raf)
|
|
observer?.disconnect()
|
|
}
|
|
}, [pathname])
|
|
|
|
return null
|
|
}
|