Skip to content

Commit 04efeb1

Browse files
committed
home page blur image, almost done
1 parent 04c4f0a commit 04efeb1

File tree

3 files changed

+58
-22
lines changed

3 files changed

+58
-22
lines changed

src/components/ImageRandom.astro

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
---
22
import ImageRandomReact from '@/components/react/ImageRandom';
3-
import { allImagesSrc } from '@/utils/image';
3+
import { getHeroImagesProps } from '@/libs/gallery/images';
44
55
// forward Astro (MDX) class attr to className React
66
const { class: className, ...props } = Astro.props;
7+
8+
const galleryImages = await getHeroImagesProps();
79
---
810

9-
<ImageRandomReact {...props} {className} {allImagesSrc} client:load />
11+
<ImageRandomReact {...props} {className} {galleryImages} client:load />

src/components/react/ImageRandom.tsx

Lines changed: 53 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,76 @@
1-
import { useEffect, useState } from 'react';
1+
import { useEffect, useMemo, useState } from 'react';
22

33
import { getRandomElementFromArray } from '@/utils/array';
44
import { cn } from '@/utils/styles';
55

6+
import type { HeroImageProps } from '@/libs/gallery/transform';
67
import type { FC, ImgHTMLAttributes } from 'react';
78

89
interface Props extends ImgHTMLAttributes<HTMLImageElement> {
910
// Important: must pass all allImagesSrc from the server or they wont be included on client
10-
allImagesSrc: string[];
11+
galleryImages: HeroImageProps[];
1112
}
1213

13-
const initialImageSrc = '';
14+
const initialImage: HeroImageProps = {
15+
blur: {
16+
src: '',
17+
width: 0,
18+
height: 0,
19+
},
20+
hero: {
21+
src: '',
22+
width: 0,
23+
height: 0,
24+
},
25+
};
1426

15-
const ImageRandomReact: FC<Props> = ({ allImagesSrc, className, ...props }) => {
16-
const [imageSrc, setImageSrc] = useState(initialImageSrc);
27+
const ImageRandomReact: FC<Props> = ({ galleryImages, className, ...props }) => {
28+
const randomImage = useMemo(() => getRandomElementFromArray(galleryImages), [galleryImages]);
1729

18-
useEffect(() => {
19-
const run = async () => {
20-
setImageSrc(getRandomElementFromArray(allImagesSrc));
21-
};
30+
const [image, setImage] = useState(initialImage);
31+
const [isLoading, setIsLoading] = useState(true);
2232

23-
run();
24-
}, [setImageSrc]);
33+
useEffect(() => {
34+
setImage(randomImage);
35+
}, [setImage, randomImage]);
2536

2637
const handleClick = async () => {
27-
setImageSrc(getRandomElementFromArray(allImagesSrc));
38+
const randomImage = getRandomElementFromArray(galleryImages);
39+
setImage(randomImage);
40+
setIsLoading(true);
2841
};
2942

3043
// Todo: use <picture srcSet> for responsive images
3144

3245
return (
33-
<img
34-
{...props}
35-
src={imageSrc}
36-
onClick={handleClick}
37-
className={cn('cursor-pointer', className)}
38-
alt="Hero image"
39-
/>
46+
<>
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.hero.src && (
58+
<img
59+
{...props}
60+
src={image.hero.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.hero.src && <div className={cn('', className)}>placeholder</div>}
73+
</>
4074
);
4175
};
4276

src/constants/gallery.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
export const EXCLUDE_IMAGES = ['avatar1.jpg'];
1+
export const EXCLUDE_IMAGES = ['avatar1.jpg', 'square-night1.jpg'];

0 commit comments

Comments
 (0)