diff --git a/site/templates/play.json.php b/site/templates/play.json.php index 5a92136..feeb766 100644 --- a/site/templates/play.json.php +++ b/site/templates/play.json.php @@ -9,6 +9,7 @@ $specificData = [ 'description' => $game->description()->value(), 'thumbnail' => $game->thumbnail()->toFile()?->url(), 'backgroundColor' => $game->backgroundColor()->value() ?: null, + 'preview' => $game->preview()->toFile()?->url(), 'playLink' => $game->playLink()->value() ?: null, ]; })->values() diff --git a/src/views/Play.svelte b/src/views/Play.svelte index aabb533..3700179 100644 --- a/src/views/Play.svelte +++ b/src/views/Play.svelte @@ -9,38 +9,46 @@ const games = $derived(data?.games ?? []) // --- State --- - let currentIndex = $state(0) // index de la sélection (mis à jour immédiatement) - let displayedIndex = $state(0) // index affiché (mis à jour au milieu de la transition) - let isOut = $state(false) - let isTransitioning = $state(false) - let slideDir = $state(1) // -1 : vers la droite, 1 : vers la gauche + let currentIndex = $state(0) // index actif (carousel + bg) + let displayedIndex = $state(0) // index du contenu affiché + let phase = $state('idle') // 'idle' | 'exiting' | 'entering' + let slideDir = $state(1) // 1 = click droite (exit gauche), -1 = click gauche (exit droite) + + // Bg crossfade + let prevBgColor = $state(null) + let bgFading = $state(false) const displayedGame = $derived(games[displayedIndex] ?? null) let t1 = null let t2 = null + let t3 = null function selectGame(i) { - if (i === currentIndex || isTransitioning || !games.length) return + if (i === currentIndex || phase !== 'idle' || !games.length) return - slideDir = i > currentIndex ? -1 : 1 - currentIndex = i - isOut = true - isTransitioning = true + // slideDir = 1 → clic à droite → content sort par la gauche, entre par la droite + slideDir = i > currentIndex ? 1 : -1 + phase = 'exiting' clearTimeout(t1) clearTimeout(t2) + clearTimeout(t3) - // Milieu : swap du contenu affiché et du fond (éléments invisibles à ce moment) + // Phase 2 (300ms) : swap contenu + carousel + bg simultanés t1 = setTimeout(() => { + prevBgColor = displayedGame?.backgroundColor ?? null displayedIndex = i - isOut = false - }, 300) + currentIndex = i + phase = 'entering' + bgFading = true - // Fin de transition - t2 = setTimeout(() => { - isTransitioning = false - }, 600) + // Fin du bg fade + t3 = setTimeout(() => { bgFading = false }, 500) + + // Fin de l'entrée + t2 = setTimeout(() => { phase = 'idle' }, 350) + }, 300) } // Réinitialisation quand on quitte la slide @@ -48,16 +56,18 @@ if (!isActive) { clearTimeout(t1) clearTimeout(t2) - currentIndex = 0 - displayedIndex = 0 - isOut = false - isTransitioning = false + clearTimeout(t3) + currentIndex = 0 + displayedIndex = 0 + phase = 'idle' + bgFading = false } }) onMount(() => () => { clearTimeout(t1) clearTimeout(t2) + clearTimeout(t3) }) @@ -67,9 +77,13 @@ style={displayedGame?.backgroundColor ? `--background-color: ${displayedGame.backgroundColor}` : ''} > - - + + {#if bgFading && prevBgColor} + + {/if} + + + + + {#if displayedGame?.preview} + + {/if} - +