Levelauswahl: größere Zahlen, Fortschrittsbild und Versuchs-Punkte entfernt, Krone durch Bestversuch-Symbol ersetzt
This commit is contained in:
parent
07ddd9c91a
commit
0dd42aa03c
|
|
@ -1,41 +1,36 @@
|
|||
<script lang="ts">
|
||||
import type { Target } from '../../game/tasks';
|
||||
import { progress } from '../../stores/progress';
|
||||
import Rocket from '../svg/Rocket.svelte';
|
||||
import Crown from '../svg/Crown.svelte';
|
||||
import Ground from '../svg/Ground.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';
|
||||
|
||||
type Props = { target: Target; onClick: (t: Target) => void };
|
||||
let { target, onClick }: Props = $props();
|
||||
|
||||
const bestStage = $derived(($progress.perTarget[target]?.top5[0]?.stage ?? 0) as number);
|
||||
const runs = $derived($progress.perTarget[target]?.runs ?? 0);
|
||||
// Fortschritt 0..1 → Höhe der Mini-Rakete in der Karte (Stufe 4 = Sterne = ganz oben)
|
||||
const progressFraction = $derived(Math.min(bestStage / 4, 1));
|
||||
const masteredAtStars = $derived(bestStage >= 4);
|
||||
const bestStage = $derived(($progress.perTarget[target]?.top5[0]?.stage ?? 0) as number);
|
||||
|
||||
// Bester Versuch → sein Stufen-Symbol (statt Krone).
|
||||
const SYMBOL: Record<number, { c: typeof Balloon; size: number }> = {
|
||||
0: { c: Ground, size: 40 },
|
||||
1: { c: Balloon, size: 34 },
|
||||
2: { c: Cloud, size: 48 },
|
||||
3: { c: Moon, size: 38 },
|
||||
4: { c: Star, size: 36 },
|
||||
};
|
||||
</script>
|
||||
|
||||
<button class="card" type="button" onclick={() => onClick(target)} aria-label={`Zielzahl ${target}`}>
|
||||
<div class="number">{target}</div>
|
||||
<div class="track" aria-hidden="true">
|
||||
<div class="rocket-wrap" style="bottom: calc({progressFraction * 100}% - 18px)">
|
||||
<Rocket size={36} flameAnimated={false} />
|
||||
</div>
|
||||
<div class="dot dot-1"></div>
|
||||
<div class="dot dot-2"></div>
|
||||
<div class="dot dot-3"></div>
|
||||
<div class="dot dot-4"></div>
|
||||
<div class="dot dot-5"></div>
|
||||
</div>
|
||||
<div class="footer">
|
||||
{#if masteredAtStars}
|
||||
<Crown size={28} />
|
||||
<span class="number">{target}</span>
|
||||
<span class="best" aria-hidden="true">
|
||||
{#if runs > 0}
|
||||
{@const Best = SYMBOL[bestStage].c}
|
||||
<Best size={SYMBOL[bestStage].size} />
|
||||
{/if}
|
||||
<span class="runs" aria-label={`${runs} Runden gespielt`}>
|
||||
{#each Array(Math.min(runs, 5)) as _, i (i)}
|
||||
<span class="run-dot"></span>
|
||||
{/each}
|
||||
</span>
|
||||
</div>
|
||||
</span>
|
||||
</button>
|
||||
|
||||
<style>
|
||||
|
|
@ -47,61 +42,21 @@
|
|||
min-width: 0;
|
||||
padding: 12px;
|
||||
display: grid;
|
||||
grid-template-rows: auto 1fr auto;
|
||||
gap: 6px;
|
||||
grid-template-rows: 1fr auto;
|
||||
place-items: center;
|
||||
transition: transform 0.12s ease;
|
||||
}
|
||||
.card:active { transform: scale(0.96); }
|
||||
|
||||
.number {
|
||||
font-size: clamp(48px, 8vw, 80px);
|
||||
font-size: clamp(64px, 13vw, 124px);
|
||||
font-weight: 800;
|
||||
color: var(--c-text);
|
||||
text-align: center;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.track {
|
||||
position: relative;
|
||||
background: linear-gradient(to top, #6cc26c 0%, #6cc26c 8%, #b6e3ff 30%, #6fb3ff 70%, #1a2c5c 100%);
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.rocket-wrap {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
transition: bottom 0.4s cubic-bezier(0.2, 0.8, 0.2, 1);
|
||||
}
|
||||
|
||||
.dot {
|
||||
position: absolute;
|
||||
left: 4px;
|
||||
width: 4px;
|
||||
height: 4px;
|
||||
border-radius: 50%;
|
||||
background: rgba(255, 255, 255, 0.7);
|
||||
}
|
||||
.dot-1 { bottom: 18%; }
|
||||
.dot-2 { bottom: 38%; }
|
||||
.dot-3 { bottom: 58%; }
|
||||
.dot-4 { bottom: 78%; }
|
||||
.dot-5 { bottom: 92%; background: var(--c-star); width: 6px; height: 6px; }
|
||||
|
||||
.footer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
min-height: 32px;
|
||||
padding: 0 4px;
|
||||
}
|
||||
.runs { display: flex; gap: 3px; }
|
||||
.run-dot {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 50%;
|
||||
background: var(--c-rocket-fin);
|
||||
opacity: 0.5;
|
||||
.best {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
min-height: 48px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user