portfolio : load mockup before gallery animation images. related to #55

Defer GalleryAnimation rendering until mockup image is fully loaded.
Ensures mockup has bandwidth priority over gallery images.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
isUnknown 2026-04-03 12:13:26 +02:00
parent 701c5d1f56
commit c6c7ad3fca

View file

@ -11,6 +11,8 @@
// --- State ---
let currentIndex = $state(0)
let sectionEl = $state(null)
let mockupEl = $state(null)
let mockupReady = $state(false)
// --- Derived ---
const isActive = $derived(slides.active?.id === 'portfolio')
@ -128,6 +130,21 @@
}
})
// --- Mockup priority: render gallery only after mockup is loaded ---
$effect(() => {
mockupReady = false
if (!mockupEl) return
const img = mockupEl.querySelector('img')
if (!img) return
if (img.complete && img.naturalWidth > 0) {
mockupReady = true
return
}
const onLoad = () => { mockupReady = true }
img.addEventListener('load', onLoad, { once: true })
return () => img.removeEventListener('load', onLoad)
})
// --- Effect: reset when slide deactivated ---
// wasActive évite que clearAnchor() s'exécute au montage initial
// (isActive est false avant l'initialisation des slides)
@ -147,9 +164,11 @@
</script>
{#key currentIndex}
{#if mockupReady}
<div class="portfolio-gallery mobile-only" aria-hidden="true">
<GalleryAnimation images={currentProject.imagesGallery} backgroundColor={currentProject.galleryBackgroundColor} backgroundImage={currentProject.galleryBackgroundImage} mode={currentProject.galleryAnimationMode} secondsPerImage={currentProject.secondsPerImage} />
</div>
{/if}
{/key}
<section
@ -160,13 +179,15 @@
>
{#if currentProject}
{#key currentIndex}
<!-- Galerie animation (gauche desktop / plein écran mobile) -->
<!-- Galerie animation (gauche desktop / plein écran mobile) — attend le mockup -->
{#if mockupReady}
<div class="portfolio-gallery desktop-only" aria-hidden="true">
<GalleryAnimation images={currentProject.imagesGallery} backgroundColor={currentProject.galleryBackgroundColor} backgroundImage={currentProject.galleryBackgroundImage} mode={currentProject.galleryAnimationMode} secondsPerImage={currentProject.secondsPerImage} />
</div>
{/if}
<!-- Mockup device (centre) -->
<div class="portfolio-mockup portfolio-mockup--{currentProject.galleryAnimationMode}">
<!-- Mockup device (centre) — prioritaire -->
<div class="portfolio-mockup portfolio-mockup--{currentProject.galleryAnimationMode}" bind:this={mockupEl}>
<ResponsivePicture
src={currentProject.mockup}
srcset={currentProject.mockupSrcset}