Magnetic fill
hoverPoint at itThe fill blooms from the point the cursor entered, so the button feels aimed at rather than switched on.
→Source
export function MagneticFill() {
const x = useMotionValue(50);
const y = useMotionValue(50);
// The fill blooms from wherever the pointer entered, not from the centre.
const background = useMotionTemplate`radial-gradient(140% 140% at ${x}% ${y}%, var(--accent) 0%, transparent 68%)`;
return (
<button
type="button"
onPointerMove={(event) => {
const rect = event.currentTarget.getBoundingClientRect();
x.set(((event.clientX - rect.left) / rect.width) * 100);
y.set(((event.clientY - rect.top) / rect.height) * 100);
}}
className="spec-label group relative overflow-hidden border border-border-strong px-5 py-3 text-foreground transition-colors duration-300 hover:text-accent-contrast"
>
{/* The fill lives on its own layer so it can fade in from nothing. */}
<motion.span
aria-hidden
style={{ background }}
className="absolute inset-0 opacity-0 transition-opacity duration-300 group-hover:opacity-100"
/>
<span className="relative">Hover me</span>
</button>
);
}