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:
parent
600ce937a3
commit
11a2c623cb
4 changed files with 57 additions and 3 deletions
|
|
@ -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'],
|
||||||
|
],
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
28
src/components/ui/ResponsivePicture.svelte
Normal file
28
src/components/ui/ResponsivePicture.svelte
Normal 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>
|
||||||
|
|
@ -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%;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue