ionian/packages/client/src/components/gallery/LazyImage.tsx
2024-04-07 17:58:05 +09:00

38 lines
1.2 KiB
TypeScript

import { useEffect, useRef, useState } from "react";
export function LazyImage({ src, alt, className }: { src: string; alt: string; className?: string; }) {
const ref = useRef<HTMLImageElement>(null);
const [loaded, setLoaded] = useState(false);
useEffect(() => {
if (ref.current) {
const observer = new IntersectionObserver((entries) => {
if (entries.some(x => x.isIntersecting)) {
setLoaded(true);
ref.current?.animate([
{ opacity: 0 },
{ opacity: 1 }
], {
duration: 300,
easing: "ease-in-out"
});
observer.disconnect();
}
}, {
rootMargin: "200px",
threshold: 0
});
observer.observe(ref.current);
return () => {
observer.disconnect();
};
}
}, []);
return <img
ref={ref}
src={loaded ? src : undefined}
alt={alt}
className={className}
loading="lazy" />;
}