Magic Card
svelte-animations/magic-cardFreeBlock
A spotlight effect that follows your mouse cursor and highlights borders on hover.
Install it
npx shadcn@latest add https://sv-animations.vercel.app/r/magic-card.jsonSource
1<script lang="ts">2 import { motion, useMotionTemplate, useMotionValue } from "motion-sv";3 import { cn } from "$UTILS$";4 import type { Snippet } from "svelte";56 interface MagicCardProps {7 /** Card content */8 children?: Snippet;9 /** Additional CSS classes */10 class?: string;11 /** Size of the gradient circle */12 gradientSize?: number;13 /** Color of the gradient overlay */14 gradientColor?: string;15 /** Opacity of the gradient overlay */16 gradientOpacity?: number;17 /** Starting color of the border gradient */18 gradientFrom?: string;19 /** Ending color of the border gradient */20 gradientTo?: string;21 }2223 let {24 children,25 class: className,26 gradientSize = 200,27 gradientColor = "#262626",28 gradientOpacity = 0.8,29 gradientFrom = "#9E7AFF",30 gradientTo = "#FE8BBB",31 }: MagicCardProps = $props();3233 let mouseX = $derived(useMotionValue(-gradientSize));34 let mouseY = $derived(useMotionValue(-gradientSize));3536 let borderGradient = $derived(37 useMotionTemplate`radial-gradient(${gradientSize}px circle at ${mouseX}px ${mouseY}px, ${gradientFrom}, ${gradientTo}, var(--border) 100%)`38 );39 let overlayGradient = $derived(40 useMotionTemplate`radial-gradient(${gradientSize}px circle at ${mouseX}px ${mouseY}px, ${gradientColor}, transparent 100%)`41 );4243 const reset = () => {44 mouseX.set(-gradientSize);45 mouseY.set(-gradientSize);46 };4748 const handlePointerMove = (e: PointerEvent) => {49 const target = e.currentTarget as HTMLElement;50 const rect = target.getBoundingClientRect();51 mouseX.set(e.clientX - rect.left);52 mouseY.set(e.clientY - rect.top);53 };5455 // Reset on mount56 $effect(() => {57 reset();58 });5960 // Global event listeners61 $effect(() => {62 const handleGlobalPointerOut = (e: PointerEvent) => {63 if (!e.relatedTarget) {64 reset();65 }66 };6768 const handleVisibility = () => {69 if (document.visibilityState !== "visible") {70 reset();71 }72 };7374 window.addEventListener("pointerout", handleGlobalPointerOut);75 window.addEventListener("blur", reset);76 document.addEventListener("visibilitychange", handleVisibility);7778 return () => {79 window.removeEventListener("pointerout", handleGlobalPointerOut);80 window.removeEventListener("blur", reset);81 document.removeEventListener("visibilitychange", handleVisibility);82 };83 });84</script>8586<div87 class={cn("group relative rounded-[inherit]", className)}88 onpointermove={handlePointerMove}89 onpointerleave={reset}90 onpointerenter={reset}91 role="region"92>93 <motion.div94// … truncated
What it pulls in
npm packages
Files it writes
More from Svelte Animations
All 66 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Animated Beamanimated-beam | Svelte Animations | Blocks | Free | 1 dep · 6 files | |
| Animated Circular Progress Baranimated-circular-progress-bar | Svelte Animations | Blocks | Free | no deps · 2 files | |
| Animated Gradient Textanimated-gradient-text | Svelte Animations | Blocks | Free | no deps · 2 files | |
| Animated Grid Patternanimated-grid-pattern | Svelte Animations | Blocks | Free | 1 dep · 2 files | |
| Animated Listanimated-list | Svelte Animations | Blocks | Free | 1 dep · 2 files | |
| Animated Shiny Textanimated-shiny-text | Svelte Animations | Blocks | Free | no deps | |
| Animated Theme Toggleranimated-theme-toggler | Svelte Animations | Blocks | Free | no deps · 2 files | |
| Arc Timelinearc-timeline | Svelte Animations | Blocks | Free | no deps · 3 files |
