From a923e1b226617218c50b8830ec4fe8324857f193 Mon Sep 17 00:00:00 2001 From: Aaron Wood Date: Sat, 11 Apr 2026 23:30:39 -0400 Subject: [PATCH] feat: add snow atmosphere effect MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit tsParticles snow — 60–300 flakes depending on intensity, size variation for depth, gentle drift via random speed + curved paths. Appears in atmosphere panel between Rain and Embers. Co-Authored-By: Claude Sonnet 4.6 --- client/src/components/AtmospherePanel.tsx | 3 +++ client/src/components/ParticleOverlay.tsx | 11 ++++++-- client/src/lib/atmosphereTypes.ts | 2 ++ client/src/lib/particleConfigs.ts | 31 +++++++++++++++++++++++ 4 files changed, 45 insertions(+), 2 deletions(-) diff --git a/client/src/components/AtmospherePanel.tsx b/client/src/components/AtmospherePanel.tsx index 6ce70ef..dd06e1c 100644 --- a/client/src/components/AtmospherePanel.tsx +++ b/client/src/components/AtmospherePanel.tsx @@ -8,6 +8,7 @@ const EFFECTS: { key: EffectKey; emoji: string; label: string }[] = [ { key: "fog", emoji: "🌫", label: "Fog" }, { key: "fire", emoji: "🔥", label: "Fire" }, { key: "rain", emoji: "🌧", label: "Rain" }, + { key: "snow", emoji: "❄️", label: "Snow" }, { key: "embers", emoji: "✨", label: "Embers" }, ]; @@ -26,6 +27,7 @@ export default function AtmospherePanel({ fog: atmosphere.fog.intensity, fire: atmosphere.fire.intensity, rain: atmosphere.rain.intensity, + snow: atmosphere.snow.intensity, embers: atmosphere.embers.intensity, }); const containerRef = useRef(null); @@ -48,6 +50,7 @@ export default function AtmospherePanel({ fog: atmosphere.fog.intensity, fire: atmosphere.fire.intensity, rain: atmosphere.rain.intensity, + snow: atmosphere.snow.intensity, embers: atmosphere.embers.intensity, }); }, [atmosphere]); diff --git a/client/src/components/ParticleOverlay.tsx b/client/src/components/ParticleOverlay.tsx index ad6d70b..c1adf66 100644 --- a/client/src/components/ParticleOverlay.tsx +++ b/client/src/components/ParticleOverlay.tsx @@ -2,7 +2,7 @@ import { useEffect, useState } from "react"; import Particles, { initParticlesEngine } from "@tsparticles/react"; import { loadSlim } from "@tsparticles/slim"; import type { AtmosphereState } from "../lib/atmosphereTypes"; -import { getRainConfig, getEmbersConfig } from "../lib/particleConfigs"; +import { getRainConfig, getSnowConfig, getEmbersConfig } from "../lib/particleConfigs"; // Module-level singleton so the engine is only initialised once let enginePromise: Promise | null = null; @@ -28,7 +28,7 @@ export default function ParticleOverlay({ atmosphere }: ParticleOverlayProps) { if (!ready) return null; - const { rain, embers } = atmosphere; + const { rain, snow, embers } = atmosphere; return ( <> @@ -39,6 +39,13 @@ export default function ParticleOverlay({ atmosphere }: ParticleOverlayProps) { options={getRainConfig(rain.intensity)} /> )} + {snow.active && ( + + )} {embers.active && (