Ergebnis-Animationen auf Seiten-Zonen begrenzen, damit sie die Karten nie überdecken
This commit is contained in:
parent
8947a28e59
commit
dde6271cf1
|
|
@ -8,55 +8,58 @@
|
|||
|
||||
let { stage }: { stage: Stage } = $props();
|
||||
|
||||
// Deko-Positionen rahmen die zentrierte Highscore-Spalte ein (Mitte bleibt frei).
|
||||
// l/t/b in %, s = Symbolgröße, d = Animationsdauer (s), dl = Verzögerung (s).
|
||||
type Deco = { l: number; t?: number; b?: number; s: number; d: number; dl: number };
|
||||
// Deko lebt ausschließlich in zwei Seiten-Zonen links und rechts der zentrierten
|
||||
// Highscore-Spalte. Die Zonen klammern die Spalte aus und sind geclippt, sodass
|
||||
// keine Animation jemals über eine Karte läuft.
|
||||
// l = Position in % innerhalb der Zone, t/b = oben/unten in %, s = Größe,
|
||||
// d = Dauer (s), dl = Verzögerung (s), side = Zone.
|
||||
type Side = 'l' | 'r';
|
||||
type Deco = { side: Side; l: number; t?: number; b?: number; s: number; d: number; dl: number };
|
||||
|
||||
const balloons: Deco[] = [
|
||||
{ l: 9, t: 60, s: 66, d: 4.5, dl: 0 },
|
||||
{ l: 21, t: 26, s: 46, d: 5.2, dl: 0.6 },
|
||||
{ l: 82, t: 54, s: 72, d: 4.0, dl: 0.3 },
|
||||
{ l: 90, t: 22, s: 50, d: 5.6, dl: 0.9 },
|
||||
{ l: 5, t: 36, s: 42, d: 4.8, dl: 1.2 },
|
||||
{ l: 74, t: 80, s: 40, d: 5.0, dl: 0.4 },
|
||||
{ side: 'l', l: 55, t: 58, s: 62, d: 4.5, dl: 0 },
|
||||
{ side: 'l', l: 25, t: 26, s: 44, d: 5.2, dl: 0.6 },
|
||||
{ side: 'l', l: 70, t: 82, s: 38, d: 5.0, dl: 0.4 },
|
||||
{ side: 'r', l: 40, t: 54, s: 68, d: 4.0, dl: 0.3 },
|
||||
{ side: 'r', l: 65, t: 22, s: 48, d: 5.6, dl: 0.9 },
|
||||
{ side: 'r', l: 20, t: 78, s: 40, d: 4.8, dl: 1.2 },
|
||||
];
|
||||
|
||||
const clouds: Deco[] = [
|
||||
{ l: 3, t: 15, s: 96, d: 9, dl: 0 },
|
||||
{ l: 58, t: 22, s: 120, d: 11, dl: 1 },
|
||||
{ l: 11, t: 72, s: 84, d: 10, dl: 0.5 },
|
||||
{ l: 70, t: 76, s: 104, d: 8.5, dl: 1.5 },
|
||||
{ l: 83, t: 44, s: 76, d: 9.5, dl: 0.8 },
|
||||
{ side: 'l', l: 18, t: 16, s: 88, d: 9, dl: 0 },
|
||||
{ side: 'l', l: 42, t: 70, s: 78, d: 10, dl: 0.5 },
|
||||
{ side: 'l', l: 58, t: 44, s: 68, d: 9.5, dl: 0.8 },
|
||||
{ side: 'r', l: 22, t: 24, s: 100, d: 11, dl: 1 },
|
||||
{ side: 'r', l: 40, t: 78, s: 92, d: 8.5, dl: 1.5 },
|
||||
];
|
||||
|
||||
const moonStars: Deco[] = [
|
||||
{ l: 14, t: 24, s: 24, d: 2.2, dl: 0 },
|
||||
{ l: 24, t: 58, s: 18, d: 2.8, dl: 0.5 },
|
||||
{ l: 8, t: 74, s: 22, d: 2.4, dl: 0.9 },
|
||||
{ l: 88, t: 60, s: 20, d: 2.6, dl: 0.3 },
|
||||
{ l: 18, t: 40, s: 14, d: 3.0, dl: 1.1 },
|
||||
{ l: 72, t: 30, s: 16, d: 2.5, dl: 0.7 },
|
||||
{ side: 'l', l: 30, t: 24, s: 24, d: 2.2, dl: 0 },
|
||||
{ side: 'l', l: 55, t: 58, s: 18, d: 2.8, dl: 0.5 },
|
||||
{ side: 'l', l: 18, t: 76, s: 22, d: 2.4, dl: 0.9 },
|
||||
{ side: 'r', l: 65, t: 62, s: 20, d: 2.6, dl: 0.3 },
|
||||
{ side: 'r', l: 35, t: 44, s: 16, d: 3.0, dl: 1.1 },
|
||||
{ side: 'r', l: 72, t: 32, s: 16, d: 2.5, dl: 0.7 },
|
||||
];
|
||||
|
||||
const stars: Deco[] = [
|
||||
{ l: 10, t: 18, s: 28, d: 2.2, dl: 0 },
|
||||
{ l: 22, t: 46, s: 20, d: 2.6, dl: 0.6 },
|
||||
{ l: 8, t: 70, s: 24, d: 2.4, dl: 1.0 },
|
||||
{ l: 30, t: 80, s: 16, d: 3.0, dl: 0.3 },
|
||||
{ l: 90, t: 20, s: 26, d: 2.3, dl: 0.8 },
|
||||
{ l: 78, t: 46, s: 18, d: 2.7, dl: 0.2 },
|
||||
{ l: 92, t: 70, s: 22, d: 2.5, dl: 1.2 },
|
||||
{ l: 70, t: 80, s: 16, d: 2.9, dl: 0.5 },
|
||||
{ l: 16, t: 32, s: 14, d: 3.1, dl: 1.4 },
|
||||
{ l: 84, t: 34, s: 14, d: 2.8, dl: 0.9 },
|
||||
{ side: 'l', l: 25, t: 18, s: 28, d: 2.2, dl: 0 },
|
||||
{ side: 'l', l: 55, t: 46, s: 20, d: 2.6, dl: 0.6 },
|
||||
{ side: 'l', l: 18, t: 70, s: 24, d: 2.4, dl: 1.0 },
|
||||
{ side: 'l', l: 65, t: 82, s: 16, d: 3.0, dl: 0.3 },
|
||||
{ side: 'l', l: 40, t: 32, s: 14, d: 3.1, dl: 1.4 },
|
||||
{ side: 'r', l: 60, t: 20, s: 26, d: 2.3, dl: 0.8 },
|
||||
{ side: 'r', l: 35, t: 46, s: 18, d: 2.7, dl: 0.2 },
|
||||
{ side: 'r', l: 70, t: 70, s: 22, d: 2.5, dl: 1.2 },
|
||||
{ side: 'r', l: 30, t: 82, s: 16, d: 2.9, dl: 0.5 },
|
||||
{ side: 'r', l: 55, t: 34, s: 14, d: 2.8, dl: 0.9 },
|
||||
];
|
||||
|
||||
const grass: Deco[] = [
|
||||
{ l: 7, b: 2, s: 48, d: 3.0, dl: 0 },
|
||||
{ l: 23, b: 2, s: 38, d: 3.4, dl: 0.4 },
|
||||
{ l: 69, b: 2, s: 44, d: 2.8, dl: 0.2 },
|
||||
{ l: 86, b: 2, s: 36, d: 3.2, dl: 0.6 },
|
||||
{ l: 47, b: 2, s: 34, d: 3.0, dl: 0.5 },
|
||||
{ side: 'l', l: 25, b: 2, s: 46, d: 3.0, dl: 0 },
|
||||
{ side: 'l', l: 60, b: 2, s: 38, d: 3.4, dl: 0.4 },
|
||||
{ side: 'r', l: 30, b: 2, s: 44, d: 2.8, dl: 0.2 },
|
||||
{ side: 'r', l: 65, b: 2, s: 36, d: 3.2, dl: 0.6 },
|
||||
];
|
||||
|
||||
function pos(d: Deco): string {
|
||||
|
|
@ -65,38 +68,61 @@
|
|||
}
|
||||
</script>
|
||||
|
||||
<div class="ambience" aria-hidden="true">
|
||||
{#snippet layer(side: Side)}
|
||||
{#if stage === 1}
|
||||
{#each balloons as d, i (i)}
|
||||
{#each balloons.filter((d) => d.side === side) as d, i (i)}
|
||||
<span class="deco bob" style={pos(d)}><Balloon size={d.s} /></span>
|
||||
{/each}
|
||||
{:else if stage === 2}
|
||||
{#each clouds as d, i (i)}
|
||||
{#each clouds.filter((d) => d.side === side) as d, i (i)}
|
||||
<span class="deco drift" style={pos(d)}><Cloud size={d.s} opacity={0.92} /></span>
|
||||
{/each}
|
||||
{:else if stage === 3}
|
||||
<span class="deco glow" style="left:80%; top:14%; --dur:5s; animation-delay:0s"><Moon size={86} /></span>
|
||||
{#each moonStars as d, i (i)}
|
||||
{#if side === 'r'}
|
||||
<span class="deco glow" style="left:42%; top:14%; --dur:5s; animation-delay:0s"><Moon size={80} /></span>
|
||||
{/if}
|
||||
{#each moonStars.filter((d) => d.side === side) as d, i (i)}
|
||||
<span class="deco twinkle" style={pos(d)}><Star size={d.s} color="#fff7c8" /></span>
|
||||
{/each}
|
||||
{:else if stage >= 4}
|
||||
{#each stars as d, i (i)}
|
||||
{#each stars.filter((d) => d.side === side) as d, i (i)}
|
||||
<span class="deco twinkle" style={pos(d)}><Star size={d.s} /></span>
|
||||
{/each}
|
||||
{:else}
|
||||
{#each grass as d, i (i)}
|
||||
{#each grass.filter((d) => d.side === side) as d, i (i)}
|
||||
<span class="deco sway" style={pos(d)}><Ground size={d.s} /></span>
|
||||
{/each}
|
||||
{/if}
|
||||
{/snippet}
|
||||
|
||||
<div class="ambience" aria-hidden="true">
|
||||
<div class="zone left">{@render layer('l')}</div>
|
||||
<div class="zone right">{@render layer('r')}</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
/* --reserve = halbe Kartenbreite (60px) + Abstand. So bleibt die zentrierte
|
||||
Spalte garantiert frei und die Zonen clippen alles, was hineinragen würde. */
|
||||
.ambience {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
overflow: hidden;
|
||||
pointer-events: none;
|
||||
z-index: 1;
|
||||
--reserve: 80px;
|
||||
}
|
||||
.zone {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
.zone.left {
|
||||
left: 0;
|
||||
right: calc(50% + var(--reserve));
|
||||
}
|
||||
.zone.right {
|
||||
left: calc(50% + var(--reserve));
|
||||
right: 0;
|
||||
}
|
||||
.deco {
|
||||
position: absolute;
|
||||
|
|
@ -111,8 +137,8 @@
|
|||
|
||||
.drift { animation: drift var(--dur, 9s) ease-in-out infinite alternate; }
|
||||
@keyframes drift {
|
||||
from { transform: translateX(-26px); }
|
||||
to { transform: translateX(26px); }
|
||||
from { transform: translateX(-22px); }
|
||||
to { transform: translateX(22px); }
|
||||
}
|
||||
|
||||
.twinkle { animation: twinkle var(--dur, 2.4s) ease-in-out infinite; }
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user