diff --git a/assets/ts/mobile/galleryImage.tsx b/assets/ts/mobile/galleryImage.tsx index 7b7f6a6..07a5c9d 100644 --- a/assets/ts/mobile/galleryImage.tsx +++ b/assets/ts/mobile/galleryImage.tsx @@ -1,4 +1,5 @@ -import { onMount, type JSX } from 'solid-js' +import { type gsap } from 'gsap' +import { createEffect, on, onMount, type JSX } from 'solid-js' import invariant from 'tiny-invariant' import type { ImageJSON } from '../resources' @@ -14,40 +15,83 @@ export default function GalleryImage(props: { let img: HTMLImageElement | undefined let loadingDiv: HTMLDivElement | undefined - let _gsap: typeof gsap + let _gsap: typeof gsap | undefined + let gsapPromise: Promise | undefined + let revealed = false const [state] = useState() + const revealImage = async (): Promise => { + if (revealed) return + revealed = true + + invariant(img, 'ref must be defined') + invariant(loadingDiv, 'loadingDiv must be defined') + + gsapPromise ??= loadGsap() + + try { + _gsap ??= await gsapPromise + } catch (e) { + console.log(e) + } + + if (_gsap === undefined) { + img.style.opacity = '1' + loadingDiv.style.opacity = '0' + return + } + + if (state().index !== props.ij.index) { + _gsap.set(img, { opacity: 1 }) + _gsap.set(loadingDiv, { opacity: 0 }) + return + } + + _gsap.to(img, { + opacity: 1, + delay: 0.5, + duration: 0.5, + ease: 'power3.out' + }) + _gsap.to(loadingDiv, { opacity: 0, duration: 0.5, ease: 'power3.in' }) + } + onMount(() => { - loadGsap() + gsapPromise = loadGsap() .then((g) => { _gsap = g + return g }) .catch((e) => { console.log(e) + throw e }) + img?.addEventListener( 'load', () => { - invariant(img, 'ref must be defined') - invariant(loadingDiv, 'loadingDiv must be defined') - if (state().index !== props.ij.index) { - _gsap.set(img, { opacity: 1 }) - _gsap.set(loadingDiv, { opacity: 0 }) - } else { - _gsap.to(img, { - opacity: 1, - delay: 0.5, - duration: 0.5, - ease: 'power3.out' - }) - _gsap.to(loadingDiv, { opacity: 0, duration: 0.5, ease: 'power3.in' }) - } + void revealImage() }, { once: true, passive: true } ) + + if (props.load && img?.complete && img.currentSrc !== '') { + void revealImage() + } }) + createEffect( + on( + () => props.load, + (load) => { + if (!load || img === undefined || !img.complete || img.currentSrc === '') return + void revealImage() + }, + { defer: true } + ) + ) + return ( <>