Feat: page Portfolio avec galerie animée, navigation par scroll/touch/clavier
All checks were successful
Deploy / Deploy to Production (push) Successful in 18s
All checks were successful
Deploy / Deploy to Production (push) Successful in 18s
- Composable useScrollNav partagé entre Expertise et Portfolio (wheel/touch/clavier) - GalleryAnimation : 3 colonnes CSS défilantes infinies avec décalage et delay - Portfolio : golden grid, mockup centré, infos projet, sidebar vignettes navigables - API portfolio.json.php alignée sur blueprint project.yml (catchphrase, images_gallery, mockup, keywords, external_links) - Variable --ease-standard partagée dans variables.css - Alias @composables ajouté dans vite.config.js - Refactor Expertise pour utiliser le composable (comportement identique) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
feb300f76e
commit
0b563b4697
9 changed files with 505 additions and 125 deletions
50
src/components/ui/GalleryAnimation.svelte
Normal file
50
src/components/ui/GalleryAnimation.svelte
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
<script>
|
||||
/**
|
||||
* GalleryAnimation — animation CSS de galerie en 3 colonnes défilantes.
|
||||
* @prop {string[]} images — URLs des images
|
||||
* @prop {number} secondsPerImage — durée par image (défaut: 8s)
|
||||
*/
|
||||
let { images = [], secondsPerImage = 8 } = $props()
|
||||
|
||||
const columns = $derived.by(() => {
|
||||
const count = images.length
|
||||
const duration = count * secondsPerImage
|
||||
const defs = [
|
||||
{ offset: 0, delay: 0 },
|
||||
{ offset: Math.floor(count / 3), delay: duration / 4 },
|
||||
{ offset: 0, delay: duration / 2 },
|
||||
]
|
||||
return defs.map(({ offset, delay }) => ({
|
||||
images: shiftImages(images, offset),
|
||||
delay,
|
||||
duration,
|
||||
}))
|
||||
})
|
||||
|
||||
function shiftImages(imgs, offset) {
|
||||
if (!offset) return imgs
|
||||
return [...imgs.slice(offset), ...imgs.slice(0, offset)]
|
||||
}
|
||||
</script>
|
||||
|
||||
<div
|
||||
class="gallery-animation gallery-animation--vertical"
|
||||
style="--gallery-duration: {columns[0]?.duration ?? 24}s"
|
||||
>
|
||||
{#each columns as col}
|
||||
<div class="gallery-animation__column">
|
||||
<div
|
||||
class="gallery-animation__track"
|
||||
style="animation-delay: -{col.delay}s"
|
||||
>
|
||||
<!-- Images × 2 pour le défilement infini -->
|
||||
{#each col.images as src}
|
||||
<img class="gallery-animation__image" {src} alt="" aria-hidden="true" loading="lazy" />
|
||||
{/each}
|
||||
{#each col.images as src}
|
||||
<img class="gallery-animation__image" {src} alt="" aria-hidden="true" loading="lazy" />
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
Loading…
Add table
Add a link
Reference in a new issue