38 lines
1.2 KiB
TypeScript
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" />;
|
|
}
|