Highscore: Stufen-Symbole statt Rakete, Krone nur für den Bestwert

This commit is contained in:
schmop 2026-05-31 16:12:29 +02:00
parent 9c971ad717
commit 30d2e36085

View File

@ -1,8 +1,13 @@
<script lang="ts"> <script lang="ts">
import type { Target } from '../../game/tasks'; import type { Target } from '../../game/tasks';
import type { Stage } from '../../game/stages';
import { progress } from '../../stores/progress'; import { progress } from '../../stores/progress';
import Rocket from '../svg/Rocket.svelte';
import Crown from '../svg/Crown.svelte'; import Crown from '../svg/Crown.svelte';
import Balloon from '../svg/Balloon.svelte';
import Cloud from '../svg/Cloud.svelte';
import Moon from '../svg/Moon.svelte';
import Star from '../svg/Star.svelte';
import Rainbow from '../svg/Rainbow.svelte';
type Props = { target: Target; highlightDate?: string | null }; type Props = { target: Target; highlightDate?: string | null };
let { target, highlightDate = null }: Props = $props(); let { target, highlightDate = null }: Props = $props();
@ -10,20 +15,37 @@
const top5 = $derived($progress.perTarget[target]?.top5 ?? []); const top5 = $derived($progress.perTarget[target]?.top5 ?? []);
// Slots immer 5 lang darstellen — leere Plätze bleiben grau. // Slots immer 5 lang darstellen — leere Plätze bleiben grau.
const slots = $derived(Array.from({ length: 5 }, (_, i) => top5[i] ?? null)); const slots = $derived(Array.from({ length: 5 }, (_, i) => top5[i] ?? null));
// Erreichte Stufe → passendes Symbol. Stufe 0 (Boden) hat kein Symbol (siehe Markup).
// Größen pro Symbol leicht angeglichen, da die viewBoxes unterschiedlich proportioniert sind.
const SYMBOL: Record<number, { c: typeof Balloon; size: number }> = {
1: { c: Balloon, size: 38 },
2: { c: Cloud, size: 52 },
3: { c: Moon, size: 40 },
4: { c: Star, size: 36 },
5: { c: Rainbow, size: 56 },
};
</script> </script>
<div class="column" aria-label="Beste Flüge"> <div class="column" aria-label="Beste Flüge">
{#each slots as slot, i (i)} {#each slots as slot, i (i)}
<div class="slot" class:empty={!slot} class:current={slot && highlightDate && slot.date === highlightDate}> <!-- Bester Versuch (i===0) wird nur durch die Krone markiert, nicht zusätzlich hervorgehoben. -->
<div
class="slot"
class:empty={!slot}
class:current={slot && i !== 0 && highlightDate && slot.date === highlightDate}
>
{#if slot} {#if slot}
{#if i === 0} {#if i === 0}
<span class="crown"><Crown size={28} /></span> <span class="crown"><Crown size={28} /></span>
{/if} {/if}
<Rocket size={44} flameAnimated={false} /> <span class="symbol" aria-label={`Stufe ${slot.stage}`}>
<span class="stage-label" aria-label={`Stufe ${slot.stage}`}> {#if slot.stage === 0}
{#each Array(slot.stage) as _, dotIndex (dotIndex)} <span class="ground" aria-hidden="true"></span>
<span class="stage-dot"></span> {:else}
{/each} {@const Symbol = SYMBOL[slot.stage as Stage].c}
<Symbol size={SYMBOL[slot.stage as Stage].size} />
{/if}
</span> </span>
{:else} {:else}
<div class="placeholder"></div> <div class="placeholder"></div>
@ -46,7 +68,6 @@
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
gap: 8px;
padding: 4px 8px; padding: 4px 8px;
min-height: 56px; min-height: 56px;
} }
@ -63,12 +84,16 @@
left: 50%; left: 50%;
transform: translateX(-50%); transform: translateX(-50%);
} }
.stage-label { display: flex; gap: 3px; } .symbol {
.stage-dot { display: flex;
width: 6px; align-items: center;
height: 6px; justify-content: center;
border-radius: 50%; }
background: var(--c-rocket-window); .ground {
width: 40px;
height: 18px;
border-radius: 40px 40px 0 0;
background: linear-gradient(to top, #4ea34e, var(--c-ground));
} }
.placeholder { .placeholder {
width: 32px; width: 32px;