Like button with particles
The heart fills with color, gives a little bounce and throws out a small ring of particles.
Settings
Code
import { useState } from "react";
import { AnimatePresence, motion } from "framer-motion";
import { Heart } from "lucide-react";
interface ParticleLikeButtonProps {
color?: string;
particles?: number;
}
export default function ParticleLikeButton({
color = "#d25563",
particles = 8,
}: ParticleLikeButtonProps) {
const [liked, setLiked] = useState(false);
return (
<button
type="button"
aria-label="Like"
aria-pressed={liked}
onClick={() => setLiked((v) => !v)}
className="relative grid h-14 w-14 place-items-center rounded-full bg-white dark:bg-[#1c1c1e] text-[#1d1d1f] dark:text-[#f5f5f7] shadow-[0_1px_2px_rgba(0,0,0,0.03),0_8px_28px_rgba(0,0,0,0.05)]"
>
<motion.span
animate={{ scale: liked ? [1, 1.35, 1] : 1 }}
transition={{ type: "spring", stiffness: 300, damping: 30 }}
>
<Heart
className="h-6 w-6"
fill={liked ? color : "transparent"}
stroke={liked ? color : "currentColor"}
/>
</motion.span>
<AnimatePresence>
{liked &&
Array.from({ length: particles }, (_, i) => (
<motion.i
key={i}
className="absolute h-1 w-1 rounded-full"
style={{ backgroundColor: color }}
initial={{ x: 0, y: 0, opacity: 1 }}
animate={{
x: Math.cos((i / particles) * Math.PI * 2) * 30,
y: Math.sin((i / particles) * Math.PI * 2) * 30,
opacity: 0,
}}
exit={{ opacity: 0 }}
transition={{ duration: 0.55 }}
/>
))}
</AnimatePresence>
</button>
);
}
Prompt for AI
Paste it into ChatGPT, Claude or Cursor and it will adapt the block to your project with these settings, even if you don’t use React.
More in Buttons
Where to use it
A like should feel good to press, otherwise nobody bothers. This heart fills, jumps slightly and scatters a few dots, like on the social apps people already know. Use it to save a recipe, favorite a listing or react to a post. Small as it is, an animated like button is often the most pressed thing on a page.
Eight particles is about right; more than that starts to look like confetti. Pick a color that belongs to your brand rather than the default red if hearts are not your thing. Tapping again removes the like, so it works as a real toggle.