Magnetic Button
wise-ui/magnetic-buttonFreeComponent
A button that magnetically attracts toward the cursor on hover.
Live preview
live · rendered by the registry
Rendered by wise-ui on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://wise-ui.com/r/magnetic-button.jsonSource
1"use client"23import * as React from "react"4import { motion, useMotionValue, useSpring } from "motion/react"5import { cn } from "@/registry/wise-ui/lib/utils"67interface MagneticButtonProps8 extends React.ButtonHTMLAttributes<HTMLButtonElement> {9 /** How far the button can travel toward the cursor (px) */10 strength?: number11 /** Radius around the button that activates the magnetic pull (px) */12 range?: number13 children: React.ReactNode14}1516const springConfig = { stiffness: 200, damping: 15, mass: 0.5 }1718const MagneticButton = React.forwardRef<19 HTMLButtonElement,20 MagneticButtonProps21>(22 (23 {24 strength = 12,25 range = 150,26 children,27 disabled,28 className,29 ...props30 },31 ref32 ) => {33 const containerRef = React.useRef<HTMLDivElement>(null)3435 const rawX = useMotionValue(0)36 const rawY = useMotionValue(0)37 const x = useSpring(rawX, springConfig)38 const y = useSpring(rawY, springConfig)3940 React.useEffect(() => {41 const el = containerRef.current42 if (!el || disabled) return4344 function handleMouseMove(e: MouseEvent) {45 const rect = el!.getBoundingClientRect()46 const centerX = rect.left + rect.width / 247 const centerY = rect.top + rect.height / 248 const distX = e.clientX - centerX49 const distY = e.clientY - centerY50 const dist = Math.sqrt(distX * distX + distY * distY)5152 if (dist < range) {53 const pull = 1 - dist / range54 rawX.set(distX * pull * (strength / range) * 2)55 rawY.set(distY * pull * (strength / range) * 2)56 } else {57 rawX.set(0)58 rawY.set(0)59 }60 }6162 function handleMouseLeave() {63 rawX.set(0)64 rawY.set(0)65 }6667 window.addEventListener("mousemove", handleMouseMove)68 el.addEventListener("mouseleave", handleMouseLeave)69 return () => {70 window.removeEventListener("mousemove", handleMouseMove)71 el.removeEventListener("mouseleave", handleMouseLeave)72 }73 }, [disabled, range, strength, rawX, rawY])7475 return (76 <motion.div77 ref={containerRef}78 className="inline-flex"79 style={{ x, y }}80 >81 <button82 ref={ref}83 disabled={disabled}84 className={cn(85 "relative inline-flex cursor-pointer items-center gap-2 rounded-md border border-border bg-background px-4 py-2 text-sm font-medium text-foreground transition-colors hover:bg-accent",86// … truncated
What it pulls in
npm packages
Files it writes
More from wise-ui
All 20 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Animated Tabsanimated-tabs | wise-ui | Components | Free | 3 deps | |
| Border Beamborder-beam | wise-ui | Components | Free | 3 deps | |
| Data Tabledata-table | wise-ui | Components | Free | 3 deps | |
| Dockdock | wise-ui | Components | Free | 3 deps | |
| Dot Matrixdot-matrix | wise-ui | Components | Free | 2 deps | |
| Editable Texteditable-text | wise-ui | Components | Free | 4 deps | |
| Gradient Sidebargradient-sidebar | wise-ui | Components | Free | 3 deps | |
| Kanban Boardkanban-board | wise-ui | Components | Free | 6 deps |
