Back to Discover
CardsAdvanced
3D Tilt Card
A card that physically tilts and rotates in 3D space relative to the cursor's position.
Live Preview
3D Tilt Card
Hover over this card to physically tilt it in 3D space based on your mouse.
"use client";
import { useRef } from "react";
import { motion, useMotionValue, useSpring, useTransform } from "framer-motion";
export function TiltCard() {
const ref = useRef<HTMLDivElement>(null);
const x = useMotionValue(0);
const y = useMotionValue(0);
const mouseXSpring = useSpring(x, { stiffness: 300, damping: 20 });
const mouseYSpring = useSpring(y, { stiffness: 300, damping: 20 });
const rotateX = useTransform(mouseYSpring, [-0.5, 0.5], ["17.5deg", "-17.5deg"]);
const rotateY = useTransform(mouseXSpring, [-0.5, 0.5], ["-17.5deg", "17.5deg"]);
const handleMouseMove = (e: React.MouseEvent<HTMLDivElement>) => {
if (!ref.current) return;
const rect = ref.current.getBoundingClientRect();
const width = rect.width;
const height = rect.height;
const mouseX = e.clientX - rect.left;
const mouseY = e.clientY - rect.top;
const xPct = mouseX / width - 0.5;
const yPct = mouseY / height - 0.5;
x.set(xPct);
y.set(yPct);
};
const handleMouseLeave = () => {
x.set(0);
y.set(0);
};
return (
<div className="flex items-center justify-center w-full h-96 bg-[#0a0a0a] rounded-xl border border-border [perspective:1000px]">
<motion.div
ref={ref}
onMouseMove={handleMouseMove}
onMouseLeave={handleMouseLeave}
style={{ rotateY, rotateX, transformStyle: "preserve-3d" }}
className="w-64 h-80 rounded-xl bg-zinc-900 border border-zinc-800 shadow-2xl p-6 relative flex flex-col justify-end overflow-hidden group"
>
<div style={{ transform: "translateZ(50px)" }} className="relative z-10 pointer-events-none">
<h3 className="text-xl font-bold text-white mb-2">3D Tilt Card</h3>
<p className="text-sm text-zinc-400">Hover over this card to physically tilt it in 3D space based on your mouse.</p>
</div>
</motion.div>
</div>
);
}