Magnetic button
Here's a breakdown of the animation.
- Track the pointer relative to the button center on
mousemove. - Scale that offset with
STRENGTH, then clamp it toMAX_DISTANCEso the pull never feels too extreme. - Animate the button position with a spring transition so it snaps back smoothly on
mouseleave.
The core of the effect is this pattern:
let x = (clientX - (left + width / 2)) * STRENGTH;
let y = (clientY - (top + height / 2)) * STRENGTH;
const distance = Math.hypot(x, y);
if (distance > MAX_DISTANCE) {
const scale = MAX_DISTANCE / distance;
x *= scale;
y *= scale;
}
<motion.div
animate={{ x, y }}
transition={{ type: "spring", stiffness: 150, damping: 15, mass: 0.1 }}
/>Magnetic Button