Opti: images galerie portfolio en srcset webp

Kirby: preset 'gallery' + 'gallery-webp' (200→800px, qualité 80)
API: images_gallery retourne {src, srcset, webp} au lieu d'une simple URL
GalleryAnimation: <picture> + srcset, sizes 15vw desktop / 33vw mobile
decoding="async" ajouté

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
isUnknown 2026-03-06 16:41:50 +01:00
parent 88379fe073
commit 88a5c78d7a
3 changed files with 44 additions and 12 deletions

View file

@ -84,13 +84,30 @@ return [
// Thumbs
'thumbs' => [
'quality' => 80,
'srcsets' => [
'default' => [
'300w' => ['width' => 300],
'600w' => ['width' => 600],
'900w' => ['width' => 900],
'1200w' => ['width' => 1200],
],
// Galerie portfolio — desktop ~15vw, mobile ~33vw (3 colonnes)
// Widths couvrent 1x et 2x retina pour les deux breakpoints
'gallery' => [
'200w' => ['width' => 200],
'300w' => ['width' => 300],
'400w' => ['width' => 400],
'600w' => ['width' => 600],
'900w' => ['width' => 900],
'1200w' => ['width' => 1200]
]
]
'800w' => ['width' => 800],
],
'gallery-webp' => [
'200w' => ['width' => 200, 'format' => 'webp'],
'300w' => ['width' => 300, 'format' => 'webp'],
'400w' => ['width' => 400, 'format' => 'webp'],
'600w' => ['width' => 600, 'format' => 'webp'],
'800w' => ['width' => 800, 'format' => 'webp'],
],
],
],
];

View file

@ -8,7 +8,11 @@ $specificData = [
'catchphrase' => $project->catchphrase()->value(),
'description' => $project->description()->value(),
'thumbnail' => $project->thumbnail()->toFile()?->url(),
'images_gallery' => $project->images_gallery()->toFiles()->map(fn($f) => $f->url())->values(),
'images_gallery' => $project->images_gallery()->toFiles()->map(fn($f) => [
'src' => $f->url(),
'srcset' => $f->srcset('gallery'),
'webp' => $f->srcset('gallery-webp'),
])->values(),
'mockup' => $project->mockup()->toFile()?->url(),
'keywords' => $project->keywords()->toStructure()->map(fn($i) => [
'label' => $i->label()->value(),

View file

@ -1,8 +1,8 @@
<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)
* @prop {Array<{src: string, srcset: string, webp: string}>} images
* @prop {number} secondsPerImage — durée par image (défaut: 8s)
*/
let { images = [], secondsPerImage = 8 } = $props()
@ -38,11 +38,22 @@
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 [col.images, col.images] as set}
{#each set as img}
<picture>
<source type="image/webp" srcset={img.webp} sizes="(max-width: 700px) 33vw, 15vw" />
<img
class="gallery-animation__image"
src={img.src}
srcset={img.srcset}
sizes="(max-width: 700px) 33vw, 15vw"
alt=""
aria-hidden="true"
loading="lazy"
decoding="async"
/>
</picture>
{/each}
{/each}
</div>
</div>