Magnetic button

Here's a breakdown of the animation.

  1. Track the pointer relative to the button center on mousemove.
  2. Scale that offset with STRENGTH, then clamp it to MAX_DISTANCE so the pull never feels too extreme.
  3. 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 }}
/>