Files
songs2yt/components/ScrollReveal.tsx
T
2026-07-17 02:23:59 +02:00

59 lines
1.2 KiB
TypeScript

"use client";
import { useEffect, useRef, useState, type ReactNode } from "react";
type Direction = "up" | "left" | "right";
type Props = {
children: ReactNode;
className?: string;
delay?: number;
direction?: Direction;
};
const OFFSET: Record<Direction, string> = {
up: "translate-y-10",
left: "-translate-x-10",
right: "translate-x-10",
};
export function ScrollReveal({
children,
className = "",
delay = 0,
direction = "up",
}: Props) {
const ref = useRef<HTMLDivElement>(null);
const [visible, setVisible] = useState(false);
useEffect(() => {
const el = ref.current;
if (!el) return;
const observer = new IntersectionObserver(
([entry]) => {
if (entry.isIntersecting) {
setVisible(true);
observer.unobserve(el);
}
},
{ threshold: 0.15, rootMargin: "0px 0px -40px 0px" },
);
observer.observe(el);
return () => observer.disconnect();
}, []);
return (
<div
ref={ref}
className={`transition-all duration-700 ease-out ${className} ${
visible ? "translate-x-0 translate-y-0 opacity-100" : `opacity-0 ${OFFSET[direction]}`
}`}
style={{ transitionDelay: `${delay}ms` }}
>
{children}
</div>
);
}