mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-21 22:11:11 -05:00
Refactor code structure and remove redundant changes
This commit is contained in:
80
src-old/components/common/LazyImage.tsx
Normal file
80
src-old/components/common/LazyImage.tsx
Normal file
@@ -0,0 +1,80 @@
|
||||
/**
|
||||
* LazyImage Component
|
||||
* Implements lazy loading for images using Intersection Observer
|
||||
* Only loads images when they're scrolled into view
|
||||
*/
|
||||
|
||||
import { useState, useEffect, useRef } from 'react';
|
||||
|
||||
interface LazyImageProps {
|
||||
src: string;
|
||||
alt: string;
|
||||
className?: string;
|
||||
onLoad?: () => void;
|
||||
onError?: (e: React.SyntheticEvent<HTMLImageElement, Event>) => void;
|
||||
}
|
||||
|
||||
export function LazyImage({
|
||||
src,
|
||||
alt,
|
||||
className = '',
|
||||
onLoad,
|
||||
onError
|
||||
}: LazyImageProps) {
|
||||
const [isLoaded, setIsLoaded] = useState(false);
|
||||
const [isInView, setIsInView] = useState(false);
|
||||
const [hasError, setHasError] = useState(false);
|
||||
const imgRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (!imgRef.current) return;
|
||||
|
||||
const observer = new IntersectionObserver(
|
||||
([entry]) => {
|
||||
if (entry.isIntersecting) {
|
||||
setIsInView(true);
|
||||
observer.disconnect();
|
||||
}
|
||||
},
|
||||
{
|
||||
rootMargin: '100px', // Start loading 100px before visible
|
||||
threshold: 0.01,
|
||||
}
|
||||
);
|
||||
|
||||
observer.observe(imgRef.current);
|
||||
|
||||
return () => observer.disconnect();
|
||||
}, []);
|
||||
|
||||
const handleLoad = () => {
|
||||
setIsLoaded(true);
|
||||
onLoad?.();
|
||||
};
|
||||
|
||||
const handleError = (e: React.SyntheticEvent<HTMLImageElement, Event>) => {
|
||||
setHasError(true);
|
||||
onError?.(e);
|
||||
};
|
||||
|
||||
return (
|
||||
<div ref={imgRef} className={`relative ${className}`}>
|
||||
{!isInView || hasError ? (
|
||||
// Loading skeleton or error state
|
||||
<div className="w-full h-full bg-muted animate-pulse rounded" />
|
||||
) : (
|
||||
<img
|
||||
src={src}
|
||||
alt={alt}
|
||||
onLoad={handleLoad}
|
||||
onError={handleError}
|
||||
className={`w-full h-full object-cover transition-opacity duration-300 ${
|
||||
isLoaded ? 'opacity-100' : 'opacity-0'
|
||||
}`}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
LazyImage.displayName = 'LazyImage';
|
||||
Reference in New Issue
Block a user