Compare commits

..

3 Commits

4 changed files with 25 additions and 7 deletions

View File

@ -9,7 +9,16 @@
const PALETTE = ['#ff5555', '#ffa84a', '#ffe34a', '#6cdc6c', '#4ab3ff', '#b06cff']; const PALETTE = ['#ff5555', '#ffa84a', '#ffe34a', '#6cdc6c', '#4ab3ff', '#b06cff'];
// triggerKey kommt von $game.stageBumpKey — das Lesen abonniert (Svelte 5) den ganzen
// game-Store, daher feuert dieser Effekt bei JEDEM Timer-Tick (~60×/s). Ohne Wertvergleich
// würde er die Partikel jede Frame neu erzeugen und die fly-Animation endlos bei 0% neu
// starten → flackernde Punkte in der Mitte. Nur bei echtem Wechsel von triggerKey auslösen.
let prevTrigger = 0;
let hideTimer: ReturnType<typeof setTimeout> | null = null;
$effect(() => { $effect(() => {
if (triggerKey === prevTrigger) return;
prevTrigger = triggerKey;
if (triggerKey === 0) return; if (triggerKey === 0) return;
counter++; counter++;
const seed = counter; const seed = counter;
@ -21,10 +30,16 @@
size: 8 + Math.random() * 8, size: 8 + Math.random() * 8,
})); }));
active = true; active = true;
const timeout = setTimeout(() => { if (hideTimer) clearTimeout(hideTimer);
hideTimer = setTimeout(() => {
active = false; active = false;
}, 700); }, 700);
return () => clearTimeout(timeout); });
// Timer beim Verlassen aufräumen (der Effekt oben kehrt meist früh zurück und gibt
// selbst keine Cleanup-Funktion mehr zurück).
$effect(() => () => {
if (hideTimer) clearTimeout(hideTimer);
}); });
</script> </script>

View File

@ -115,7 +115,10 @@
will-change: transform; will-change: transform;
} }
.float { animation: float var(--dur, 3.6s) ease-in-out infinite alternate; } /* fill-mode: backwards hält schon während des animation-delay den 0%-Zustand. Ohne das
sitzt das Element verzögert bei transform:none und springt beim Animationsstart auf den
0%-Keyframe — das sichtbare „Springen" in den ersten Sekunden. */
.float { animation: float var(--dur, 3.6s) ease-in-out infinite alternate backwards; }
/* translate3d/translateZ erzwingen eine echte GPU-Compositor-Ebene — WebKit/Safari /* translate3d/translateZ erzwingen eine echte GPU-Compositor-Ebene — WebKit/Safari
rendert 3D-transformierte Elemente flüssig, 2D-Transforms ruckeln dort sonst anfangs. */ rendert 3D-transformierte Elemente flüssig, 2D-Transforms ruckeln dort sonst anfangs. */
@keyframes float { @keyframes float {
@ -123,13 +126,13 @@
100% { transform: translate3d(0, -30px, 0) rotate(5deg); } 100% { transform: translate3d(0, -30px, 0) rotate(5deg); }
} }
.drift { animation: drift var(--dur, 8s) ease-in-out infinite alternate; } .drift { animation: drift var(--dur, 8s) ease-in-out infinite alternate backwards; }
@keyframes drift { @keyframes drift {
from { transform: translate3d(-55px, 0, 0); } from { transform: translate3d(-55px, 0, 0); }
to { transform: translate3d(55px, 0, 0); } to { transform: translate3d(55px, 0, 0); }
} }
.twinkle { animation: twinkle var(--dur, 2.2s) ease-in-out infinite; } .twinkle { animation: twinkle var(--dur, 2.2s) ease-in-out infinite backwards; }
@keyframes twinkle { @keyframes twinkle {
0%, 100% { opacity: 0.25; transform: scale(0.5) translateZ(0); } 0%, 100% { opacity: 0.25; transform: scale(0.5) translateZ(0); }
50% { opacity: 1; transform: scale(1.35) translateZ(0); } 50% { opacity: 1; transform: scale(1.35) translateZ(0); }

View File

@ -26,7 +26,7 @@ export type Settings = {
export const DEFAULT_SETTINGS: Settings = { export const DEFAULT_SETTINGS: Settings = {
schemaVersion: SCHEMA_VERSION, schemaVersion: SCHEMA_VERSION,
roundSeconds: 60, roundSeconds: 15,
soundOn: true, soundOn: true,
}; };

View File

@ -5,7 +5,7 @@ export const ROUND_SECONDS_OPTIONS = [15, 30, 60] as const;
const initial: Settings = const initial: Settings =
typeof window === 'undefined' typeof window === 'undefined'
? { schemaVersion: 1, roundSeconds: 60, soundOn: true } ? { schemaVersion: 1, roundSeconds: 15, soundOn: true }
: loadSettings(); : loadSettings();
export const settings = writable<Settings>(initial); export const settings = writable<Settings>(initial);