Draggable Card
PremiumA physics-driven draggable card with 3D tilt, glare effect, and momentum-based spring animations. Scatter them across the screen and drag to explore.
Interactive Demo
Drag the cardsIf its your first day at Fight Club, you have to fight.
Tyler Durden
The Narrator
Iceland
Japan
Norway
New Zealand
Canada
Installation
Install the draggable-card via the shadcn CLI:
bash
npx shadcn@latest add "https://dexterityui.vercel.app/r/draggable-card.json"Requires motion (framer-motion).
Props
DraggableCardContainer
| Prop | Type | Description |
|---|---|---|
className | string | Additional CSS classes. Applies perspective: 3000px by default. |
children | ReactNode | DraggableCardBody components to render inside. |
DraggableCardBody
| Prop | Type | Description |
|---|---|---|
className | string | Position and rotation classes (e.g. absolute top-10 left-[20%] rotate-[-5deg]). |
children | ReactNode | Card content — images, text, etc. |
Features
🎯3D tilt — card rotates to follow cursor position with spring physics
💎Glare effect — dynamic white overlay that shifts with mouse movement
⚡Momentum — cards carry velocity on release with spring bounce
🖱️Drag constraints — cards stay within the viewport boundaries
🔄Spring reset — tilt smoothly resets to zero when released
📐Perspective container — 3000px perspective for realistic 3D depth
Source
tsx
"use client";
import { cn } from "@/lib/utils";
import React, { useRef, useState, useEffect } from "react";
import {
motion,
useMotionValue,
useSpring,
useTransform,
animate,
useVelocity,
useAnimationControls,
} from "motion/react";
export const DraggableCardBody = ({
className,
children,
}: {
className?: string;
children?: React.ReactNode;
}) => {
const mouseX = useMotionValue(0);
const mouseY = useMotionValue(0);
const cardRef = useRef<HTMLDivElement>(null);
const controls = useAnimationControls();
// ... spring physics, 3D tilt, glare, drag constraints
// Full source: registry/default/draggable-card/draggable-card.tsx
};
export const DraggableCardContainer = ({
className,
children,
}: {
className?: string;
children?: React.ReactNode;
}) => {
return (
<div className={cn("[perspective:3000px]", className)}>{children}</div>
);
};