app: refonte JWE v2 - SvelteKit 2 + Svelte 5 + MapLibre, 4 modes de jeu, API anti-triche, ecran Cas B 'Pwen blinde', i18n FR/GCF, PWA
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
<script lang="ts">
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
interface Props {
|
||||
dureeMs?: number; // fenêtre du bonus temps (60 s)
|
||||
actif?: boolean;
|
||||
}
|
||||
|
||||
let { dureeMs = 60000, actif = true }: Props = $props();
|
||||
|
||||
let ecoule = $state(0);
|
||||
let intervalle: ReturnType<typeof setInterval> | null = null;
|
||||
const depart = Date.now();
|
||||
|
||||
// Fraction restante, de 1 (plein) à 0 (vide) — informatif, jamais anxiogène.
|
||||
let fraction = $derived(Math.max(0, 1 - ecoule / dureeMs));
|
||||
let termine = $derived(ecoule >= dureeMs);
|
||||
|
||||
const R = 15.5;
|
||||
const C = 2 * Math.PI * R;
|
||||
|
||||
/** Temps écoulé en ms (pour le bonus côté /api/guess). */
|
||||
export function tempsMs(): number {
|
||||
return Date.now() - depart;
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
if (actif) {
|
||||
intervalle = setInterval(() => {
|
||||
ecoule = Date.now() - depart;
|
||||
if (ecoule >= dureeMs && intervalle) {
|
||||
clearInterval(intervalle);
|
||||
intervalle = null;
|
||||
}
|
||||
}, 250);
|
||||
}
|
||||
return () => {
|
||||
if (intervalle) clearInterval(intervalle);
|
||||
};
|
||||
});
|
||||
</script>
|
||||
|
||||
<div class="timer" class:termine role="timer" aria-label="Minuteur" title="Minuteur">
|
||||
<svg viewBox="0 0 36 36" aria-hidden="true">
|
||||
<circle class="fond" cx="18" cy="18" r={R} />
|
||||
<circle
|
||||
class="reste"
|
||||
cx="18"
|
||||
cy="18"
|
||||
r={R}
|
||||
stroke-dasharray={C}
|
||||
stroke-dashoffset={C * (1 - fraction)}
|
||||
transform="rotate(-90 18 18)"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.timer {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
svg {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.fond {
|
||||
fill: rgba(255, 253, 248, 0.85);
|
||||
stroke: var(--oki-sable-fonce);
|
||||
stroke-width: 3;
|
||||
}
|
||||
|
||||
.reste {
|
||||
fill: none;
|
||||
stroke: var(--oki-vert-clair); /* couleur douce, calm technology */
|
||||
stroke-width: 3;
|
||||
stroke-linecap: round;
|
||||
transition: stroke-dashoffset 0.25s linear;
|
||||
}
|
||||
|
||||
.termine .reste {
|
||||
stroke: var(--oki-sable-fonce);
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user