Magic Card
A spotlight effect that follows your mouse cursor and highlights borders on hover.
Motion
Card
Installation
Copy and paste the following code into your project.
"use client"
import React, { useCallback, useEffect } from "react"
import { motion, useMotionTemplate, useMotionValue } from "framer-motion"
import { cn } from "@/lib/utils"
export interface MagicCardProps extends React.HTMLAttributes<HTMLDivElement> {
gradientSize?: number
gradientColor?: string
gradientOpacity?: number
}
export function MagicCard({
children,
className,
gradientSize = 200,
gradientColor = "#262626",
gradientOpacity = 0.8,
}: MagicCardProps) {
const mouseX = useMotionValue(-gradientSize)
const mouseY = useMotionValue(-gradientSize)
const handleMouseMove = useCallback(
(e: React.MouseEvent<HTMLDivElement>) => {
const { left, top } = e.currentTarget.getBoundingClientRect()
mouseX.set(e.clientX - left)
mouseY.set(e.clientY - top)
},
[mouseX, mouseY]
)
const handleMouseLeave = useCallback(() => {
mouseX.set(-gradientSize)
mouseY.set(-gradientSize)
}, [mouseX, mouseY, gradientSize])
useEffect(() => {
mouseX.set(-gradientSize)
mouseY.set(-gradientSize)
}, [mouseX, mouseY, gradientSize])
return (
<div
onMouseMove={handleMouseMove}
onMouseLeave={handleMouseLeave}
className={cn(
"group relative flex size-full overflow-hidden rounded-xl bg-neutral-100 dark:bg-neutral-900 border text-black dark:text-white",
className
)}
>
<div className="relative z-10">{children}</div>
<motion.div
className="pointer-events-none absolute -inset-px rounded-xl opacity-0 transition-opacity duration-300 group-hover:opacity-100"
style={{
background: useMotionTemplate`
radial-gradient(${gradientSize}px circle at ${mouseX}px ${mouseY}px, ${gradientColor}, transparent 100%)
`,
opacity: gradientOpacity,
}}
/>
</div>
)
}
Update the import paths to match your project setup.
Props
MagicCard
Prop name | Type | Default | Description |
---|---|---|---|
children | React.ReactNode | - | The content to be rendered inside the card |
className | string | - | Additional CSS classes to apply to the card |
gradientSize | number | 200 | Size of the gradient effect |
gradientColor | string | "#262626" | Color of the gradient effect |
gradientOpacity | number | - | Opacity of the gradient effect |
gradientTransparency | number | 80 | Transparency level of the gradient effect |