51 lines
1.5 KiB
Svelte
51 lines
1.5 KiB
Svelte
|
|
<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>
|