Skip to content
Plinth

Original by Plinth · MIT

Cards

Tilt Card

A card that tilts in 3D toward your cursor.

#card#3d#tilt#hover

Install

npx shadcn@latest add https://plinthui.com/r/tilt-card.json
Open in v0
'use client';

import { useRef } from 'react';

const MAX_DEG = 10;
const FLAT = 'perspective(800px) rotateX(0deg) rotateY(0deg) scale(1)';
const SETTLE = 'transform 400ms ease';

export function TiltCard() {
  const cardRef = useRef<HTMLElement>(null);

  const handleMouseMove = (event: React.MouseEvent<HTMLElement>) => {
    const card = cardRef.current;
    if (!card) return;
    const rect = card.getBoundingClientRect();
    const px = (event.clientX - rect.left) / rect.width - 0.5;
    const py = (event.clientY - rect.top) / rect.height - 0.5;
    // Written straight to the element so the pointer never triggers a
    // re-render — the same approach spotlight-card uses.
    card.style.transition = 'none';
    card.style.transform = `perspective(800px) rotateX(${(-py * 2 * MAX_DEG).toFixed(
      2,
    )}deg) rotateY(${(px * 2 * MAX_DEG).toFixed(2)}deg) scale(1.02)`;
  };

  const handleMouseLeave = () => {
    const card = cardRef.current;
    if (!card) return;
    // The 400ms ease only plays on the way back to flat.
    card.style.transition = SETTLE;
    card.style.transform = FLAT;
  };

  const style: React.CSSProperties = {
    transform: FLAT,
    transition: SETTLE,
    willChange: 'transform',
  };

  return (
    <article
      ref={cardRef}
      onMouseMove={handleMouseMove}
      onMouseLeave={handleMouseLeave}
      style={style}
      className="h-40 w-[260px] rounded-xl border border-[#26282e] bg-[#16181c] p-5 shadow-[inset_0_1px_0_rgba(255,255,255,0.06),0_12px_28px_rgba(0,0,0,0.35)]"
    >
      <p className="text-[11px] font-semibold uppercase tracking-[0.12em] text-[#c8a96a]">Cards</p>
      <h3 className="mt-2.5 text-[17px] font-semibold text-[#ece9e2]">Tilt toward me</h3>
      <p className="mt-2 text-[13px] leading-[1.6] text-[#8a8d96]">
        The card leans after your cursor and settles back flat when you leave.
      </p>
    </article>
  );
}

More in Cards

Similar tags