{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "particle-background", "title": "Particle Background", "description": "A particle background component", "dependencies": [ "react-particles", "tsparticles-slim", "tsparticles-engine" ], "files": [ { "path": "registry/pioneerui/particle-background.tsx", "content": "\"use client\"\n\nimport { useCallback, useMemo } from \"react\"\nimport Particles from \"react-tsparticles\"\nimport { loadSlim } from \"tsparticles-slim\"\nimport type { Container, Engine } from \"tsparticles-engine\"\nimport type { ISourceOptions, MoveDirection, OutMode } from \"tsparticles-engine\"\nimport { cn } from \"@/lib/utils\"\n\nexport type ParticlePreset = \n | \"default\"\n | \"links\"\n | \"bubbles\"\n | \"snow\"\n | \"stars\"\n | \"fireflies\"\n | \"floating\"\n | \"confetti\"\n\nexport interface ParticleBackgroundProps {\n className?: string\n preset?: ParticlePreset\n color?: string\n particleCount?: number\n speed?: number\n interactive?: boolean\n zIndex?: number\n containerId?: string\n}\n\nexport function ParticleBackground({\n className,\n preset = \"default\",\n color = \"#5B21B6\",\n particleCount = 50,\n speed = 3,\n interactive = true,\n zIndex = 0,\n containerId = \"tsparticles\",\n}: ParticleBackgroundProps) {\n const particlesInit = useCallback(async (engine: Engine) => {\n await loadSlim(engine)\n }, [])\n\n const particlesLoaded = useCallback(async (container: Container | undefined) => {\n // Optional: Add any initialization after particles are loaded\n }, [])\n\n const baseConfig = useMemo(() => {\n return {\n fullScreen: {\n enable: false,\n zIndex: 0,\n },\n background: {\n color: {\n value: \"transparent\",\n },\n },\n fpsLimit: 120,\n interactivity: {\n events: {\n onClick: {\n enable: interactive,\n mode: \"push\",\n },\n onHover: {\n enable: interactive,\n mode: \"repulse\",\n },\n resize: true,\n },\n modes: {\n push: {\n quantity: 4,\n },\n repulse: {\n distance: 200,\n duration: 0.4,\n },\n },\n },\n particles: {\n color: {\n value: color,\n },\n links: {\n enable: false,\n },\n move: {\n direction: \"none\" as MoveDirection,\n enable: true,\n outModes: {\n default: \"bounce\" as OutMode,\n },\n random: false,\n speed: speed,\n straight: false,\n },\n number: {\n density: {\n enable: true,\n area: 800,\n },\n value: particleCount,\n },\n opacity: {\n value: { min: 0.1, max: 0.5 },\n },\n shape: {\n type: \"circle\",\n },\n size: {\n value: { min: 1, max: 3 },\n },\n },\n detectRetina: true,\n }\n }, [color, interactive, particleCount, speed])\n\n const presetConfigs = useMemo(\n () => ({\n default: baseConfig,\n links: {\n ...baseConfig,\n particles: {\n ...baseConfig.particles,\n links: {\n enable: true,\n distance: 150,\n color: color,\n opacity: 0.5,\n width: 1,\n },\n },\n interactivity: {\n ...baseConfig.interactivity,\n events: {\n ...baseConfig.interactivity.events,\n onHover: {\n enable: interactive,\n mode: \"grab\",\n },\n },\n modes: {\n ...baseConfig.interactivity.modes,\n grab: {\n distance: 140,\n links: {\n opacity: 0.5,\n },\n },\n },\n },\n } as ISourceOptions,\n bubbles: {\n ...baseConfig,\n particles: {\n ...baseConfig.particles,\n move: {\n ...baseConfig.particles.move,\n direction: \"none\" as MoveDirection,\n outModes: {\n default: \"out\" as OutMode,\n },\n },\n opacity: {\n value: { min: 0.1, max: 0.5 },\n animation: {\n enable: true,\n speed: 1,\n minimumValue: 0.1,\n },\n },\n size: {\n value: { min: 5, max: 15 },\n },\n },\n interactivity: {\n ...baseConfig.interactivity,\n events: {\n ...baseConfig.interactivity.events,\n onHover: {\n enable: interactive,\n mode: \"bubble\",\n },\n },\n modes: {\n ...baseConfig.interactivity.modes,\n bubble: {\n distance: 250,\n duration: 2,\n opacity: 0.8,\n size: 40,\n },\n },\n },\n } as ISourceOptions,\n snow: {\n ...baseConfig,\n particles: {\n ...baseConfig.particles,\n color: {\n value: \"#ffffff\",\n },\n move: {\n ...baseConfig.particles.move,\n direction: \"bottom\" as MoveDirection,\n outModes: {\n default: \"out\" as OutMode,\n },\n },\n size: {\n value: { min: 1, max: 4 },\n },\n },\n } as ISourceOptions,\n stars: {\n ...baseConfig,\n particles: {\n ...baseConfig.particles,\n color: {\n value: \"#ffffff\",\n },\n move: {\n ...baseConfig.particles.move,\n direction: \"none\" as MoveDirection,\n outModes: {\n default: \"out\" as OutMode,\n },\n random: true,\n },\n shape: {\n type: \"star\",\n },\n opacity: {\n value: { min: 0.1, max: 0.8 },\n animation: {\n enable: true,\n speed: 1,\n minimumValue: 0.1,\n },\n },\n },\n } as ISourceOptions,\n fireflies: {\n ...baseConfig,\n particles: {\n ...baseConfig.particles,\n color: {\n value: \"#ffeb3b\",\n },\n move: {\n ...baseConfig.particles.move,\n direction: \"none\" as MoveDirection,\n outModes: {\n default: \"out\" as OutMode,\n },\n random: true,\n },\n opacity: {\n value: { min: 0.1, max: 0.8 },\n animation: {\n enable: true,\n speed: 1,\n minimumValue: 0.1,\n },\n },\n },\n } as ISourceOptions,\n floating: {\n ...baseConfig,\n particles: {\n ...baseConfig.particles,\n move: {\n ...baseConfig.particles.move,\n direction: \"top\" as MoveDirection,\n outModes: {\n default: \"out\" as OutMode,\n },\n random: true,\n },\n shape: {\n type: [\"circle\", \"square\", \"triangle\"],\n },\n size: {\n value: { min: 3, max: 6 },\n },\n },\n interactivity: {\n ...baseConfig.interactivity,\n events: {\n ...baseConfig.interactivity.events,\n onHover: {\n enable: interactive,\n mode: \"bubble\",\n },\n },\n modes: {\n ...baseConfig.interactivity.modes,\n bubble: {\n distance: 250,\n duration: 2,\n opacity: 0.8,\n size: 10,\n },\n },\n },\n } as ISourceOptions,\n confetti: {\n ...baseConfig,\n particles: {\n ...baseConfig.particles,\n color: {\n value: [\n \"#f44336\",\n \"#e91e63\",\n \"#9c27b0\",\n \"#673ab7\",\n \"#3f51b5\",\n \"#2196f3\",\n \"#03a9f4\",\n \"#00bcd4\",\n \"#009688\",\n \"#4CAF50\",\n \"#8BC34A\",\n \"#CDDC39\",\n \"#FFEB3B\",\n \"#FFC107\",\n \"#FF9800\",\n \"#FF5722\",\n ],\n },\n move: {\n ...baseConfig.particles.move,\n direction: \"bottom\" as MoveDirection,\n outModes: {\n default: \"out\" as OutMode,\n },\n random: true,\n },\n shape: {\n type: [\"circle\", \"square\"],\n },\n opacity: {\n value: 0.6,\n },\n size: {\n value: { min: 3, max: 6 },\n },\n },\n } as ISourceOptions,\n }),\n [baseConfig, color, interactive],\n )\n\n return (\n