Sparkles Button
Install
Copy and paste the following code into your project.
"use client";
import { type AnimationSequence, useAnimate } from "motion/react";
import { Sparkles } from "lucide-react";
import { cn } from "@/lib/utils";
const random = (min: number, max: number) =>
Math.floor(Math.random() * (max - min + 1)) + min;
export default function SparklesButton({
sparklesCount = 20,
}: {
sparklesCount?: number;
}) {
const [scope, animate] = useAnimate();
const onButtonClick = () => {
const sparklesArray = Array.from({ length: sparklesCount });
const sparklesReset: AnimationSequence = sparklesArray.map((_, index) => [
`.sparkle-${index}`,
{ x: 0, y: 0 },
{ duration: 0.000001 },
]);
const sparklesAnimation: AnimationSequence = sparklesArray.map(
(_, index) => [
`.sparkle-${index}`,
{
x: random(-100, 100),
y: random(-100, 100),
scale: random(1, 2.5),
opacity: 1,
},
{ duration: 0.4, at: "<" },
],
);
const sparklesExit: AnimationSequence = sparklesArray.map((_, index) => [
`.sparkle-${index}`,
{ scale: 0, opacity: 0 },
{ duration: 0.3, at: "<" },
]);
animate([
...sparklesReset,
["button", { scale: 0.8 }, { duration: 0.1 }],
["button", { scale: 1 }, { duration: 0.1 }],
...sparklesAnimation,
["button", {}, { duration: 0.000001 }],
...sparklesExit,
]);
};
return (
<div ref={scope}>
<button
type="button"
onClick={onButtonClick}
className={cn(
"relative rounded-full border border-amber-200 bg-amber-100 p-1 group z-10",
)}
>
<div className="h-10 flex items-center justify-center gap-1 px-5 rounded-full border border-amber-500 bg-gradient-to-b from-amber-400 to-amber-500 shadow-md shadow-amber-400 text-white font-semibold group-hover:border-amber-600 group-hover:shadow-transparent transition">
Button
<Sparkles size={16} />
</div>
<span className="absolute inset-0 block pointer-events-none -z-10">
{Array.from({ length: sparklesCount }).map((_, index) => (
<svg
key={index}
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
className={`fill-amber-400 size-2 text-amber-400 opacity-0 absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 sparkle-${index}`}
>
<path d="M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z" />
<path d="M20 3v4" />
<path d="M22 5h-4" />
<path d="M4 17v2" />
<path d="M5 18H3" />
</svg>
))}
</span>
</button>
</div>
);
}