Docs
Particle Button
Particle Button
A stylish button with animated particle effects
Installation
Copy and paste the following code into your project.
"use client"
import React, { useEffect, useRef } from "react"
import { motion } from "framer-motion"
interface Particle {
x: number
y: number
vx: number
vy: number
radius: number
color: string
}
interface ParticleButtonProps {
children: React.ReactNode
className?: string
particleCount?: number
particleColors?: string[]
}
const ParticleButton: React.FC<ParticleButtonProps> = ({
children,
className = "",
particleCount = 50,
particleColors = ["#FF6B6B", "#4ECDC4", "#45B7D1", "#FFA07A", "#98D8C8"],
}) => {
const canvasRef = useRef<HTMLCanvasElement>(null)
const particlesRef = useRef<Particle[]>([])
useEffect(() => {
const canvas = canvasRef.current
if (!canvas) return
const ctx = canvas.getContext("2d")
if (!ctx) return
const createParticles = () => {
const particles: Particle[] = []
for (let i = 0; i < particleCount; i++) {
particles.push({
x: Math.random() * canvas.width,
y: Math.random() * canvas.height,
vx: (Math.random() - 0.5) * 0.2, // Consistent low velocity
vy: (Math.random() - 0.5) * 0.2, // Consistent low velocity
radius: Math.random() * 1.5 + 0.5,
color:
particleColors[Math.floor(Math.random() * particleColors.length)],
})
}
return particles
}
particlesRef.current = createParticles()
const animate = () => {
ctx.clearRect(0, 0, canvas.width, canvas.height)
particlesRef.current.forEach((particle) => {
particle.x += particle.vx
particle.y += particle.vy
if (particle.x < 0 || particle.x > canvas.width) particle.vx *= -1
if (particle.y < 0 || particle.y > canvas.height) particle.vy *= -1
ctx.beginPath()
ctx.arc(particle.x, particle.y, particle.radius, 0, Math.PI * 2)
ctx.fillStyle = particle.color
ctx.fill()
})
requestAnimationFrame(animate)
}
animate()
const handleResize = () => {
canvas.width = canvas.offsetWidth
canvas.height = canvas.offsetHeight
particlesRef.current = createParticles()
}
handleResize()
window.addEventListener("resize", handleResize)
return () => {
window.removeEventListener("resize", handleResize)
}
}, [particleCount, particleColors])
return (
<motion.button
className={`relative overflow-hidden rounded-lg px-4 py-2 font-medium text-sm uppercase tracking-wider transition-all duration-300 ease-in-out ${className}`}
style={{
background: "rgba(255, 255, 255, 0.8)",
backdropFilter: "blur(10px)",
border: "1px solid rgba(0, 0, 0, 0.1)",
boxShadow: "0 0 0 1px rgba(0, 0, 0, 0.05)",
}}
whileHover={{ scale: 1.05 }}
whileTap={{ scale: 0.95 }}
>
<canvas
ref={canvasRef}
className="absolute inset-0 w-full h-full"
style={{ mixBlendMode: "multiply" }}
/>
<span className="relative z-10 text-black font-semibold">{children}</span>
</motion.button>
)
}
export ParticleButton
Update the import paths to match your project setup.
Usage
import ParticleButton from "@/components/ui/particle-button"
export default function ParticleButtonDemo() {
return (
<div className="flex flex-col items-center justify-center">
<ParticleButton>Glass UI</ParticleButton>
</div>
)
}
Props
The ParticleButton
component accepts the following props:
children
(React.ReactNode): The content to display inside the button.className
(string, optional): Additional CSS classes to apply to the button.particleCount
(number, optional): The number of particles to render. Default is 50.particleColors
(string[], optional): An array of colors for the particles. Default is['#FF6B6B', '#4ECDC4', '#45B7D1', '#FFA07A', '#98D8C8']
.
Customization
You can customize the appearance and behavior of the Particle Button by adjusting the props:
<ParticleButton
className="bg-blue-500 text-white"
particleCount={100}
particleColors={['#FFD700', '#FF69B4', '#00CED1']}
>
Custom Particle Button
</ParticleButton>
This example creates a blue button with white text and 100 particles in gold, pink, and turquoise colors.