Skip to content

Commit 016a47d

Browse files
committed
blur loader with Image constructor, without css transition, works nicely
1 parent 2238bf7 commit 016a47d

File tree

2 files changed

+27
-28
lines changed

2 files changed

+27
-28
lines changed

docs/working-notes/todo4.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ http://localhost:3000/_image?href=/@fs/home/username/Desktop/nemanjam.github.io/
8080
// in prod
8181
http://localhost:3000/_astro/focus1.CEdGhKb3_nVk9T.webp
8282

83+
image 100% width and height, fills container that controls size
84+
8385
```
8486

8587

src/components/react/ImageRandom.tsx

Lines changed: 25 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -28,48 +28,45 @@ const ImageRandomReact: FC<Props> = ({ galleryImages, className, ...props }) =>
2828
const randomImage = useMemo(() => getRandomElementFromArray(galleryImages), [galleryImages]);
2929

3030
const [image, setImage] = useState(initialImage);
31-
const [isLoading, setIsLoading] = useState(true);
31+
const [hasLoaded, setHasLoaded] = useState(false);
3232

33+
// initial image, on mount
3334
useEffect(() => {
3435
setImage(randomImage);
3536
}, [setImage, randomImage]);
3637

38+
// handle blur -> xl image switch
39+
useEffect(() => {
40+
const img = new Image();
41+
img.src = image.xl.src;
42+
43+
img.onload = () => {
44+
setHasLoaded(true);
45+
};
46+
}, [image, setHasLoaded]);
47+
3748
const handleClick = async () => {
3849
const randomImage = getRandomElementFromArray(galleryImages);
3950
setImage(randomImage);
40-
setIsLoading(true);
51+
setHasLoaded(false);
4152
};
4253

54+
const imageSrc = hasLoaded ? image.xl.src : image.blur.src;
55+
const imageAlt = hasLoaded ? 'Hero image' : 'Blur image';
56+
4357
// Todo: use <picture srcSet> for responsive images
4458

4559
return (
4660
<>
47-
{image.blur.src && (
48-
<img
49-
{...props}
50-
src={image.blur.src}
51-
onClick={handleClick}
52-
className={cn('cursor-pointer hidden', { block: isLoading }, className)}
53-
alt="Blur image"
54-
/>
55-
)}
56-
57-
{image.xl.src && (
58-
<img
59-
{...props}
60-
src={image.xl.src}
61-
onClick={handleClick}
62-
onLoad={() => setIsLoading(false)}
63-
className={cn(
64-
'cursor-pointer transition-opacity duration-500 ease-in-out opacity-100 block',
65-
{ 'hidden opacity-0': isLoading },
66-
className
67-
)}
68-
alt="Hero image"
69-
/>
70-
)}
71-
72-
{!image.blur.src && !image.xl.src && <div className={cn('', className)}>placeholder</div>}
61+
<img
62+
{...props}
63+
src={imageSrc}
64+
alt={imageAlt}
65+
onClick={handleClick}
66+
className={cn('cursor-pointer', className)}
67+
/>
68+
69+
{!imageSrc && <div className={cn('', className)}>placeholder</div>}
7370
</>
7471
);
7572
};

0 commit comments

Comments
 (0)