Feat: images responsives vignettes Play + composant ResponsivePicture

- Config: presets thumbnail + thumbnail-webp (170/255/355/510/710w)
- play.json.php: expose thumbnailSrcset + thumbnailWebp
- Nouveau composant ResponsivePicture.svelte (src, srcset, webp, sizes, alt, cls)
- Play.svelte: utilise ResponsivePicture dans le carousel
  sizes="clamp(170px, 18.41vw, 355px)"

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
isUnknown 2026-03-10 08:08:34 +01:00
parent 600ce937a3
commit 11a2c623cb
4 changed files with 57 additions and 3 deletions

View file

@ -108,6 +108,21 @@ return [
'600w' => ['width' => 600, 'format' => 'webp'], '600w' => ['width' => 600, 'format' => 'webp'],
'800w' => ['width' => 800, 'format' => 'webp'], '800w' => ['width' => 800, 'format' => 'webp'],
], ],
// Vignettes jeux — active: clamp(170px, 18.41vw, 355px), retina 2x → 710px
'thumbnail' => [
'170w' => ['width' => 170],
'255w' => ['width' => 255],
'355w' => ['width' => 355],
'510w' => ['width' => 510],
'710w' => ['width' => 710],
],
'thumbnail-webp' => [
'170w' => ['width' => 170, 'format' => 'webp'],
'255w' => ['width' => 255, 'format' => 'webp'],
'355w' => ['width' => 355, 'format' => 'webp'],
'510w' => ['width' => 510, 'format' => 'webp'],
'710w' => ['width' => 710, 'format' => 'webp'],
],
], ],
], ],
]; ];

View file

@ -8,6 +8,8 @@ $specificData = [
'lettering' => $game->lettering()->toFile()?->url(), 'lettering' => $game->lettering()->toFile()?->url(),
'description' => $game->description()->value(), 'description' => $game->description()->value(),
'thumbnail' => $game->thumbnail()->toFile()?->url(), 'thumbnail' => $game->thumbnail()->toFile()?->url(),
'thumbnailSrcset' => $game->thumbnail()->toFile()?->srcset('thumbnail'),
'thumbnailWebp' => $game->thumbnail()->toFile()?->srcset('thumbnail-webp'),
'backgroundColor' => $game->backgroundColor()->value() ?: null, 'backgroundColor' => $game->backgroundColor()->value() ?: null,
'preview' => $game->preview()->toFile()?->url(), 'preview' => $game->preview()->toFile()?->url(),
'playLink' => $game->playLink()->value() ?: null, 'playLink' => $game->playLink()->value() ?: null,

View file

@ -0,0 +1,28 @@
<script>
/**
* Image responsive avec support WebP via <picture>.
*
* @prop {string} src — URL fallback (format original)
* @prop {string} srcset — srcset format original (ex: "200w ..., 400w ...")
* @prop {string} webp — srcset format WebP
* @prop {string} sizes — valeur de l'attribut sizes
* @prop {string} [alt] — texte alternatif
* @prop {string} [cls] — classe CSS à appliquer sur <img>
*/
let { src, srcset, webp, sizes, alt = '', cls = '' } = $props()
</script>
<picture>
{#if webp}
<source type="image/webp" srcset={webp} {sizes} />
{/if}
<img
{src}
{srcset}
{sizes}
{alt}
class={cls}
loading="lazy"
decoding="async"
/>
</picture>

View file

@ -1,6 +1,7 @@
<script> <script>
import { onMount } from 'svelte' import { onMount } from 'svelte'
import { slides } from '@state/slides.svelte' import { slides } from '@state/slides.svelte'
import ResponsivePicture from '@components/ui/ResponsivePicture.svelte'
let { data } = $props() let { data } = $props()
@ -196,7 +197,13 @@
onclick={() => selectGame(i)} onclick={() => selectGame(i)}
> >
{#if game.thumbnail} {#if game.thumbnail}
<img src={game.thumbnail} alt="" /> <ResponsivePicture
src={game.thumbnail}
srcset={game.thumbnailSrcset}
webp={game.thumbnailWebp}
sizes="clamp(170px, 18.41vw, 355px)"
alt=""
/>
{/if} {/if}
<span class="play-carousel-title">{game.title}</span> <span class="play-carousel-title">{game.title}</span>
</button> </button>
@ -360,7 +367,8 @@
width: clamp(170px, 18.41vw, 355px); width: clamp(170px, 18.41vw, 355px);
} }
.play-carousel-item button img { .play-carousel-item button img,
.play-carousel-item button :global(picture img) {
object-fit: cover; object-fit: cover;
transition: border-color 0.4s var(--ease-standard); transition: border-color 0.4s var(--ease-standard);
} }
@ -371,7 +379,8 @@
text-align: center; text-align: center;
} }
.play-carousel-item.active button img { .play-carousel-item.active button img,
.play-carousel-item.active button :global(picture img) {
border: 4px solid var(--color-primary); border: 4px solid var(--color-primary);
border-radius: 25%; border-radius: 25%;
} }