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:
parent
01adf70585
commit
37b6ca7a5f
1 changed files with 26 additions and 4 deletions
|
|
@ -11,10 +11,30 @@
|
|||
let sectionEl = $state(null)
|
||||
|
||||
// --- Derived ---
|
||||
const isActive = $derived(slides.active?.id === 'portfolio')
|
||||
const projects = $derived(data?.projects ?? [])
|
||||
const isActive = $derived(slides.active?.id === 'portfolio')
|
||||
const projects = $derived(data?.projects ?? [])
|
||||
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 ---
|
||||
const nav = createScrollNav({
|
||||
isActive: () => isActive,
|
||||
|
|
@ -24,6 +44,7 @@
|
|||
: Math.max(currentIndex - 1, 0)
|
||||
if (next === currentIndex) return false
|
||||
currentIndex = next
|
||||
setAnchor(next)
|
||||
},
|
||||
})
|
||||
|
||||
|
|
@ -44,6 +65,7 @@
|
|||
if (!isActive) {
|
||||
nav.reset()
|
||||
currentIndex = 0
|
||||
clearAnchor()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
|
@ -97,7 +119,7 @@
|
|||
<button
|
||||
class="portfolio-nav-item"
|
||||
class:active={i === currentIndex}
|
||||
onclick={() => { currentIndex = i }}
|
||||
onclick={() => { currentIndex = i; setAnchor(i) }}
|
||||
>
|
||||
<span class="portfolio-nav-number">{String(i + 1).padStart(2, '0')}</span>
|
||||
<img src={project.thumbnail} alt={project.title} />
|
||||
|
|
@ -207,7 +229,7 @@
|
|||
}
|
||||
|
||||
.portfolio-nav-item.active {
|
||||
transform: scale(1.25);
|
||||
transform: scale(1.25) translateX(-50%);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue