Feat: ancres URL par projet dans la page Portfolio

- Navigation scroll/clavier → history.replaceState('#slug')
- Clic sidebar → idem
- Chargement avec #slug dans l'URL → affiche le bon projet directement
- Quitter la slide Portfolio → efface le hash

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
isUnknown 2026-03-06 12:17:58 +01:00
parent 01adf70585
commit 37b6ca7a5f

View file

@ -15,6 +15,26 @@
const projects = $derived(data?.projects ?? []) const projects = $derived(data?.projects ?? [])
const currentProject = $derived(projects[currentIndex] ?? null) const currentProject = $derived(projects[currentIndex] ?? null)
// --- Ancres ---
function setAnchor(index) {
const slug = projects[index]?.slug
if (!slug) return
history.replaceState(null, '', '#' + slug)
}
function clearAnchor() {
history.replaceState(null, '', window.location.pathname + window.location.search)
}
// 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 (idx > 0) currentIndex = idx
})
// --- Scroll nav composable --- // --- Scroll nav composable ---
const nav = createScrollNav({ const nav = createScrollNav({
isActive: () => isActive, isActive: () => isActive,
@ -24,6 +44,7 @@
: Math.max(currentIndex - 1, 0) : Math.max(currentIndex - 1, 0)
if (next === currentIndex) return false if (next === currentIndex) return false
currentIndex = next currentIndex = next
setAnchor(next)
}, },
}) })
@ -44,6 +65,7 @@
if (!isActive) { if (!isActive) {
nav.reset() nav.reset()
currentIndex = 0 currentIndex = 0
clearAnchor()
} }
}) })
</script> </script>
@ -97,7 +119,7 @@
<button <button
class="portfolio-nav-item" class="portfolio-nav-item"
class:active={i === currentIndex} class:active={i === currentIndex}
onclick={() => { currentIndex = i }} onclick={() => { currentIndex = i; setAnchor(i) }}
> >
<span class="portfolio-nav-number">{String(i + 1).padStart(2, '0')}</span> <span class="portfolio-nav-number">{String(i + 1).padStart(2, '0')}</span>
<img src={project.thumbnail} alt={project.title} /> <img src={project.thumbnail} alt={project.title} />
@ -207,7 +229,7 @@
} }
.portfolio-nav-item.active { .portfolio-nav-item.active {
transform: scale(1.25); transform: scale(1.25) translateX(-50%);
opacity: 1; opacity: 1;
} }