diff --git a/client/src/lib/particleConfigs.ts b/client/src/lib/particleConfigs.ts index e6cfb73..5094845 100644 --- a/client/src/lib/particleConfigs.ts +++ b/client/src/lib/particleConfigs.ts @@ -1,70 +1,74 @@ import type { ISourceOptions } from "@tsparticles/engine"; -/** Intensity 0–100 → fire particle count 20–200, speed 2–8 */ +/** + * Fire — intensity 0–100 → count 80–300, speed 2–8 + * Big bright particles rising upward. Emitters not used (not in slim bundle) + * so particles respawn via outModes "out" (wrap from bottom when they exit top). + */ export function getFireConfig(intensity: number): ISourceOptions { - const count = Math.round(20 + (intensity / 100) * 180); + const count = Math.round(80 + (intensity / 100) * 220); const speed = 2 + (intensity / 100) * 6; return { fullScreen: { enable: false }, background: { opacity: 0 }, particles: { number: { value: count, density: { enable: false } }, - color: { value: ["#ff4400", "#ff8800", "#ffcc00", "#ff2200"] }, + color: { value: ["#ff2200", "#ff5500", "#ff8800", "#ffbb00", "#ffee00"] }, shape: { type: "circle" }, opacity: { - value: { min: 0.1, max: 0.8 }, - animation: { enable: true, speed: 2, startValue: "max", destroy: "min" }, + value: { min: 0.5, max: 1 }, + animation: { enable: true, speed: 2, sync: false, startValue: "random" }, }, - size: { value: { min: 1, max: 4 } }, + size: { value: { min: 4, max: 12 } }, move: { enable: true, speed: { min: speed * 0.5, max: speed }, direction: "top", random: true, straight: false, - outModes: { default: "destroy", top: "destroy" }, - }, - life: { duration: { sync: false, value: 3 }, count: 1 }, - }, - emitters: { - direction: "top", - life: { count: 0, duration: 0.1, delay: 0.1 }, - rate: { delay: 0.05, quantity: Math.max(1, Math.round(count / 20)) }, - size: { width: 100, height: 0 }, - position: { x: 50, y: 100 }, - }, - }; -} - -/** Intensity 0–100 → rain particle count 50–500, speed 5–20 */ -export function getRainConfig(intensity: number): ISourceOptions { - const count = Math.round(50 + (intensity / 100) * 450); - const speed = 5 + (intensity / 100) * 15; - return { - fullScreen: { enable: false }, - background: { opacity: 0 }, - particles: { - number: { value: count, density: { enable: false } }, - color: { value: "#7aaad8" }, - shape: { type: "circle" }, - opacity: { value: { min: 0.2, max: 0.45 } }, - size: { value: { min: 0.5, max: 1.5 } }, - move: { - enable: true, - speed: speed, - direction: "bottom", - straight: true, - angle: { value: 15, offset: 0 }, outModes: { default: "out" }, }, }, }; } -/** Intensity 0–100 → embers particle count 5–80, speed 0.2–1.5 */ +/** + * Rain — intensity 0–100 → count 100–500, speed 10–25 + * Line-shaped particles (included in slim) falling straight down. + * rotate: 10° gives a slight diagonal angle. + */ +export function getRainConfig(intensity: number): ISourceOptions { + const count = Math.round(100 + (intensity / 100) * 400); + const speed = 10 + (intensity / 100) * 15; + return { + fullScreen: { enable: false }, + background: { opacity: 0 }, + particles: { + number: { value: count, density: { enable: false } }, + color: { value: "#aaccee" }, + shape: { type: "line" }, + opacity: { value: { min: 0.4, max: 0.8 } }, + size: { value: { min: 10, max: 20 } }, + rotate: { value: 10, animation: { enable: false } }, + move: { + enable: true, + speed: speed, + direction: "bottom", + straight: true, + outModes: { default: "out" }, + }, + }, + }; +} + +/** + * Embers — intensity 0–100 → count 30–120, speed 0.3–2 + * Small glowing dots drifting slowly upward with flickering opacity. + * Noticeably slower and dimmer than fire to contrast clearly. + */ export function getEmbersConfig(intensity: number): ISourceOptions { - const count = Math.round(5 + (intensity / 100) * 75); - const speed = 0.2 + (intensity / 100) * 1.3; + const count = Math.round(30 + (intensity / 100) * 90); + const speed = 0.3 + (intensity / 100) * 1.7; return { fullScreen: { enable: false }, background: { opacity: 0 }, @@ -73,10 +77,10 @@ export function getEmbersConfig(intensity: number): ISourceOptions { color: { value: ["#ff8800", "#ffaa00", "#ffcc44", "#ff6600"] }, shape: { type: "circle" }, opacity: { - value: { min: 0.3, max: 0.9 }, - animation: { enable: true, speed: 0.5, sync: false }, + value: { min: 0.2, max: 1 }, + animation: { enable: true, speed: 0.7, sync: false, startValue: "random" }, }, - size: { value: { min: 1, max: 3 } }, + size: { value: { min: 2, max: 5 } }, move: { enable: true, speed: speed,