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">
|
<script lang="ts">
|
||||||
import type { Target } from '../../game/tasks';
|
import type { Target } from '../../game/tasks';
|
||||||
import { progress } from '../../stores/progress';
|
import { progress } from '../../stores/progress';
|
||||||
import Rocket from '../svg/Rocket.svelte';
|
import Ground from '../svg/Ground.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';
|
||||||
|
|
||||||
type Props = { target: Target; onClick: (t: Target) => void };
|
type Props = { target: Target; onClick: (t: Target) => void };
|
||||||
let { target, onClick }: Props = $props();
|
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);
|
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 bestStage = $derived(($progress.perTarget[target]?.top5[0]?.stage ?? 0) as number);
|
||||||
const progressFraction = $derived(Math.min(bestStage / 4, 1));
|
|
||||||
const masteredAtStars = $derived(bestStage >= 4);
|
// 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>
|
</script>
|
||||||
|
|
||||||
<button class="card" type="button" onclick={() => onClick(target)} aria-label={`Zielzahl ${target}`}>
|
<button class="card" type="button" onclick={() => onClick(target)} aria-label={`Zielzahl ${target}`}>
|
||||||
<div class="number">{target}</div>
|
<span class="number">{target}</span>
|
||||||
<div class="track" aria-hidden="true">
|
<span class="best" aria-hidden="true">
|
||||||
<div class="rocket-wrap" style="bottom: calc({progressFraction * 100}% - 18px)">
|
{#if runs > 0}
|
||||||
<Rocket size={36} flameAnimated={false} />
|
{@const Best = SYMBOL[bestStage].c}
|
||||||
</div>
|
<Best size={SYMBOL[bestStage].size} />
|
||||||
<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} />
|
|
||||||
{/if}
|
{/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>
|
</span>
|
||||||
</div>
|
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|
@ -47,61 +42,21 @@
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
padding: 12px;
|
padding: 12px;
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-rows: auto 1fr auto;
|
grid-template-rows: 1fr auto;
|
||||||
gap: 6px;
|
place-items: center;
|
||||||
transition: transform 0.12s ease;
|
transition: transform 0.12s ease;
|
||||||
}
|
}
|
||||||
.card:active { transform: scale(0.96); }
|
.card:active { transform: scale(0.96); }
|
||||||
|
|
||||||
.number {
|
.number {
|
||||||
font-size: clamp(48px, 8vw, 80px);
|
font-size: clamp(64px, 13vw, 124px);
|
||||||
font-weight: 800;
|
font-weight: 800;
|
||||||
color: var(--c-text);
|
color: var(--c-text);
|
||||||
text-align: center;
|
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
}
|
}
|
||||||
|
.best {
|
||||||
.track {
|
display: grid;
|
||||||
position: relative;
|
place-items: center;
|
||||||
background: linear-gradient(to top, #6cc26c 0%, #6cc26c 8%, #b6e3ff 30%, #6fb3ff 70%, #1a2c5c 100%);
|
min-height: 48px;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user