Docs
Sparkles
A configurable sparkles component that can be used as a background or as a standalone component.
Installation
Install dependencies
npm install framer-motion lucide-react
Update tailwind.config.js
Add the following to your tailwind.config.js file.
module.exports = {
theme: {
extend: {
}
}
}
Run the following command
It will create a new file sparkles.tsx
inside the components/mage-ui/background
directory.
mkdir -p components/mage-ui/background && touch components/mage-ui/background/sparkles.tsx
Paste the code
Open the newly created file and paste the following code:
"use client";
import React, { useId, useEffect, useState } from "react";
import Particles, { initParticlesEngine } from "@tsparticles/react";
import type { Container } from "@tsparticles/engine";
import { loadSlim } from "@tsparticles/slim";
import { cn } from "@/lib/utils";
import { motion, useAnimation } from "framer-motion";
type ParticlesProps = {
id?: string;
className?: string;
background?: string;
minSize?: number;
maxSize?: number;
speed?: number;
particleColor?: string;
particleDensity?: number;
};
const SparklesCore: React.FC<ParticlesProps> = (props) => {
const {
id,
className,
background,
minSize,
maxSize,
speed,
particleColor,
particleDensity,
} = props;
const [init, setInit] = useState(false);
useEffect(() => {
initParticlesEngine(async (engine) => {
await loadSlim(engine);
}).then(() => {
setInit(true);
});
}, []);
const controls = useAnimation();
const particlesLoaded = async (container?: Container) => {
if (container) {
controls.start({ opacity: 1, transition: { duration: 1 } });
}
};
const generatedId = useId();
return (
<motion.div animate={controls} className={cn("opacity-0", className)}>
{init && (
<Particles
id={id || generatedId}
className={cn("h-full w-full")}
particlesLoaded={particlesLoaded}
options={{
background: { color: { value: background || "#0d47a1" } },
fullScreen: { enable: false, zIndex: 1 },
fpsLimit: 120,
interactivity: {
events: {
onClick: { enable: true, mode: "push" },
resize: true as any,
},
modes: { push: { quantity: 4 } },
},
particles: {
color: { value: particleColor || "#ffffff" },
move: { enable: true, speed: speed || 1.5, direction: "none" },
number: { value: particleDensity || 300, density: { enable: true } },
opacity: { value: { min: 0.1, max: 1 }, animation: { enable: true } },
size: { value: { min: minSize || 1, max: maxSize || 3 } },
shape: { type: "circle" },
},
detectRetina: true,
}}
/>
)}
</motion.div>
);
};
const SparklesPreview: React.FC = () => {
return (
<div className="h-[40rem] w-full bg-black flex flex-col items-center justify-center overflow-hidden rounded-md">
<h1 className="md:text-7xl text-3xl lg:text-9xl font-bold text-center text-white relative z-20">
Mage UI
</h1>
<div className="w-[40rem] h-40 relative">
{/* Gradients */}
<div className="absolute inset-x-20 top-0 bg-gradient-to-r from-transparent via-indigo-500 to-transparent h-[2px] w-3/4 blur-sm" />
<div className="absolute inset-x-20 top-0 bg-gradient-to-r from-transparent via-indigo-500 to-transparent h-px w-3/4" />
<div className="absolute inset-x-60 top-0 bg-gradient-to-r from-transparent via-sky-500 to-transparent h-[5px] w-1/4 blur-sm" />
<div className="absolute inset-x-60 top-0 bg-gradient-to-r from-transparent via-sky-500 to-transparent h-px w-1/4" />
{/* Core component */}
<SparklesCore
background="transparent"
minSize={0.4}
maxSize={1}
particleDensity={10000}
speed={0.8}
className="w-full h-full"
particleColor="#FFFFFF"
/>
{/* Radial Gradient to prevent sharp edges */}
<div className="absolute inset-0 w-full h-full bg-black [mask-image:radial-gradient(350px_200px_at_top,transparent_20%,white)]"></div>
</div>
</div>
);
};
export default SparklesPreview;