From 436a4371da29eb51b632c032f05b2580a6305a5a Mon Sep 17 00:00:00 2001 From: isUnknown Date: Fri, 6 Mar 2026 12:23:47 +0100 Subject: [PATCH] Fix: is-animated et ancre URL au chargement MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit is-animated : double rAF garantit un paint avec le bon translateX avant d'activer la transition (évite l'animation parasite au load). Ancre : capture du hash synchrone à la création du composant + flag wasActive pour que clearAnchor() ne s'exécute pas au montage quand isActive est encore false (slides non initialisées). Co-Authored-By: Claude Sonnet 4.6 --- src/App.svelte | 5 +++-- src/views/Portfolio.svelte | 17 ++++++++++++----- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/App.svelte b/src/App.svelte index 4967b2f..6c6d110 100644 --- a/src/App.svelte +++ b/src/App.svelte @@ -38,10 +38,11 @@ let resizeTimer = null // Active la transition seulement après le premier paint à la bonne position. - // Sans ça, un chargement sur /expertise slide depuis l'accueil. + // Double rAF : le premier laisse passer un paint avec le bon translateX, + // le second active is-animated — évite l'animation parasite au chargement. $effect(() => { if (slides.all.length > 0 && !isReady) { - requestAnimationFrame(() => { isReady = true }) + requestAnimationFrame(() => requestAnimationFrame(() => { isReady = true })) } }) diff --git a/src/views/Portfolio.svelte b/src/views/Portfolio.svelte index 9510344..b5ef44b 100644 --- a/src/views/Portfolio.svelte +++ b/src/views/Portfolio.svelte @@ -15,6 +15,9 @@ const projects = $derived(data?.projects ?? []) const currentProject = $derived(projects[currentIndex] ?? null) + // Capture du hash synchrone avant que tout effect puisse le modifier + const initialHash = window.location.hash.slice(1) + // --- Ancres --- function setAnchor(index) { const slug = projects[index]?.slug @@ -28,10 +31,8 @@ // Initialisation depuis l'ancre URL — une seule fois quand projects est prêt $effect(() => { - if (projects.length === 0) return - const hash = window.location.hash.slice(1) - if (!hash) return - const idx = projects.findIndex(p => p.slug === hash) + if (projects.length === 0 || !initialHash) return + const idx = projects.findIndex(p => p.slug === initialHash) if (idx > 0) currentIndex = idx }) @@ -61,11 +62,17 @@ }) // --- Effect: reset when slide deactivated --- + // wasActive évite que clearAnchor() s'exécute au montage initial + // (isActive est false avant l'initialisation des slides) + let wasActive = false $effect(() => { - if (!isActive) { + if (isActive) { + wasActive = true + } else if (wasActive) { nav.reset() currentIndex = 0 clearAnchor() + wasActive = false } })