fix: rework particle configs for visibility and distinct looks

- Fire: remove broken emitter (not in slim bundle), bigger particles (4-12px),
  more count (80-300), outModes "out" so particles respawn continuously
- Rain: switch to line shape (in slim), size 10-20px for visible streaks,
  higher opacity and speed
- Embers: bump min size to 2-5px, increase count (30-120) for visibility

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Aaron Wood 2026-04-10 19:55:48 -04:00
parent 0b626601ac
commit ecbc696918

View file

@ -1,70 +1,74 @@
import type { ISourceOptions } from "@tsparticles/engine"; import type { ISourceOptions } from "@tsparticles/engine";
/** Intensity 0100 → fire particle count 20200, speed 28 */ /**
* Fire intensity 0100 count 80300, speed 28
* 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 { 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; const speed = 2 + (intensity / 100) * 6;
return { return {
fullScreen: { enable: false }, fullScreen: { enable: false },
background: { opacity: 0 }, background: { opacity: 0 },
particles: { particles: {
number: { value: count, density: { enable: false } }, number: { value: count, density: { enable: false } },
color: { value: ["#ff4400", "#ff8800", "#ffcc00", "#ff2200"] }, color: { value: ["#ff2200", "#ff5500", "#ff8800", "#ffbb00", "#ffee00"] },
shape: { type: "circle" }, shape: { type: "circle" },
opacity: { opacity: {
value: { min: 0.1, max: 0.8 }, value: { min: 0.5, max: 1 },
animation: { enable: true, speed: 2, startValue: "max", destroy: "min" }, animation: { enable: true, speed: 2, sync: false, startValue: "random" },
}, },
size: { value: { min: 1, max: 4 } }, size: { value: { min: 4, max: 12 } },
move: { move: {
enable: true, enable: true,
speed: { min: speed * 0.5, max: speed }, speed: { min: speed * 0.5, max: speed },
direction: "top", direction: "top",
random: true, random: true,
straight: false, 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 0100 → rain particle count 50500, speed 520 */
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" }, outModes: { default: "out" },
}, },
}, },
}; };
} }
/** Intensity 0100 → embers particle count 580, speed 0.21.5 */ /**
* Rain intensity 0100 count 100500, speed 1025
* 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 0100 count 30120, speed 0.32
* Small glowing dots drifting slowly upward with flickering opacity.
* Noticeably slower and dimmer than fire to contrast clearly.
*/
export function getEmbersConfig(intensity: number): ISourceOptions { export function getEmbersConfig(intensity: number): ISourceOptions {
const count = Math.round(5 + (intensity / 100) * 75); const count = Math.round(30 + (intensity / 100) * 90);
const speed = 0.2 + (intensity / 100) * 1.3; const speed = 0.3 + (intensity / 100) * 1.7;
return { return {
fullScreen: { enable: false }, fullScreen: { enable: false },
background: { opacity: 0 }, background: { opacity: 0 },
@ -73,10 +77,10 @@ export function getEmbersConfig(intensity: number): ISourceOptions {
color: { value: ["#ff8800", "#ffaa00", "#ffcc44", "#ff6600"] }, color: { value: ["#ff8800", "#ffaa00", "#ffcc44", "#ff6600"] },
shape: { type: "circle" }, shape: { type: "circle" },
opacity: { opacity: {
value: { min: 0.3, max: 0.9 }, value: { min: 0.2, max: 1 },
animation: { enable: true, speed: 0.5, sync: false }, animation: { enable: true, speed: 0.7, sync: false, startValue: "random" },
}, },
size: { value: { min: 1, max: 3 } }, size: { value: { min: 2, max: 5 } },
move: { move: {
enable: true, enable: true,
speed: speed, speed: speed,