feat: add ParticleOverlay component for tsParticles effects
This commit is contained in:
parent
a6e3ca6066
commit
e947e8e127
1 changed files with 75 additions and 0 deletions
75
client/src/components/ParticleOverlay.tsx
Normal file
75
client/src/components/ParticleOverlay.tsx
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
import { useEffect, useState } from "react";
|
||||
import Particles, { initParticlesEngine } from "@tsparticles/react";
|
||||
import { loadSlim } from "@tsparticles/slim";
|
||||
import type { AtmosphereState } from "../lib/atmosphereTypes";
|
||||
import { getFireConfig, getRainConfig, getEmbersConfig } from "../lib/particleConfigs";
|
||||
|
||||
// Module-level singleton so the engine is only initialised once
|
||||
let enginePromise: Promise<void> | null = null;
|
||||
function ensureEngine(): Promise<void> {
|
||||
if (!enginePromise) {
|
||||
enginePromise = initParticlesEngine(async (engine) => {
|
||||
await loadSlim(engine);
|
||||
});
|
||||
}
|
||||
return enginePromise;
|
||||
}
|
||||
|
||||
const overlayStyle: React.CSSProperties = {
|
||||
position: "fixed",
|
||||
inset: 0,
|
||||
zIndex: 9997,
|
||||
pointerEvents: "none",
|
||||
};
|
||||
|
||||
const instanceStyle: React.CSSProperties = {
|
||||
position: "absolute",
|
||||
inset: 0,
|
||||
};
|
||||
|
||||
interface ParticleOverlayProps {
|
||||
atmosphere: AtmosphereState;
|
||||
}
|
||||
|
||||
export default function ParticleOverlay({ atmosphere }: ParticleOverlayProps) {
|
||||
const [ready, setReady] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
ensureEngine().then(() => setReady(true));
|
||||
}, []);
|
||||
|
||||
if (!ready) return null;
|
||||
|
||||
const { fire, rain, embers } = atmosphere;
|
||||
const anyActive = fire.active || rain.active || embers.active;
|
||||
if (!anyActive) return null;
|
||||
|
||||
return (
|
||||
<div style={overlayStyle}>
|
||||
{fire.active && (
|
||||
<Particles
|
||||
key={`fire-${fire.intensity}`}
|
||||
id="particles-fire"
|
||||
options={getFireConfig(fire.intensity)}
|
||||
style={instanceStyle}
|
||||
/>
|
||||
)}
|
||||
{rain.active && (
|
||||
<Particles
|
||||
key={`rain-${rain.intensity}`}
|
||||
id="particles-rain"
|
||||
options={getRainConfig(rain.intensity)}
|
||||
style={instanceStyle}
|
||||
/>
|
||||
)}
|
||||
{embers.active && (
|
||||
<Particles
|
||||
key={`embers-${embers.intensity}`}
|
||||
id="particles-embers"
|
||||
options={getEmbersConfig(embers.intensity)}
|
||||
style={instanceStyle}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue