@@ -28,48 +28,45 @@ const ImageRandomReact: FC<Props> = ({ galleryImages, className, ...props }) =>
28
28
const randomImage = useMemo ( ( ) => getRandomElementFromArray ( galleryImages ) , [ galleryImages ] ) ;
29
29
30
30
const [ image , setImage ] = useState ( initialImage ) ;
31
- const [ isLoading , setIsLoading ] = useState ( true ) ;
31
+ const [ hasLoaded , setHasLoaded ] = useState ( false ) ;
32
32
33
+ // initial image, on mount
33
34
useEffect ( ( ) => {
34
35
setImage ( randomImage ) ;
35
36
} , [ setImage , randomImage ] ) ;
36
37
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
+
37
48
const handleClick = async ( ) => {
38
49
const randomImage = getRandomElementFromArray ( galleryImages ) ;
39
50
setImage ( randomImage ) ;
40
- setIsLoading ( true ) ;
51
+ setHasLoaded ( false ) ;
41
52
} ;
42
53
54
+ const imageSrc = hasLoaded ? image . xl . src : image . blur . src ;
55
+ const imageAlt = hasLoaded ? 'Hero image' : 'Blur image' ;
56
+
43
57
// Todo: use <picture srcSet> for responsive images
44
58
45
59
return (
46
60
< >
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 > }
73
70
</ >
74
71
) ;
75
72
} ;
0 commit comments