Switch fire effect from tsParticles to a full-screen Three.js WebGL shader using layered FBM noise for volumetric-style flames rising from the bottom of the screen. Also fix rain/embers canvas banding by switching them to tsParticles fullScreen mode. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
51 lines
1.3 KiB
TypeScript
51 lines
1.3 KiB
TypeScript
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";
|
|
|
|
// 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;
|
|
}
|
|
|
|
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 { rain, embers } = atmosphere;
|
|
|
|
return (
|
|
<>
|
|
{rain.active && (
|
|
<Particles
|
|
key={`rain-${rain.intensity}`}
|
|
id="particles-rain"
|
|
options={getRainConfig(rain.intensity)}
|
|
/>
|
|
)}
|
|
{embers.active && (
|
|
<Particles
|
|
key={`embers-${embers.intensity}`}
|
|
id="particles-embers"
|
|
options={getEmbersConfig(embers.intensity)}
|
|
/>
|
|
)}
|
|
</>
|
|
);
|
|
}
|