← Components/Cards

HoverTiltCard

hovertiltcard-1779378412565.tsx
'use client'
import { useRef, useState } from 'react'

interface CardData {
  title: string
  subtitle: string
  stat: string
  icon: string
  color: string
}

const cards: CardData[] = [
  { title: 'Revenue', subtitle: 'Monthly recurring', stat: '$48,200', icon: '💰', color: '#C9A84C' },
  { title: 'Users', subtitle: 'Active this month', stat: '12,847', icon: '👥', color: '#6366f1' },
  { title: 'Components', subtitle: 'Published today', stat: '1,200+', icon: '⚡', color: '#22c55e' },
]

function TiltCard({ card }: { card: CardData }) {
  const ref = useRef<HTMLDivElement>(null)
  const [transform, setTransform] = useState('perspective(1000px) rotateX(0) rotateY(0)')
  const [shine, setShine] = useState({ x: 50, y: 50, opacity: 0 })

  function onMove(e: React.MouseEvent) {
    const el = ref.current!
    const rect = el.getBoundingClientRect()
    const x = (e.clientX - rect.left) / rect.width
    const y = (e.clientY - rect.top) / rect.height
    const tiltX = (y - 0.5) * -20
    const tiltY = (x - 0.5) * 20
    setTransform(`perspective(1000px) rotateX(${tiltX}deg) rotateY(${tiltY}deg) scale(1.03)`)
    setShine({ x: x * 100, y: y * 100, opacity: 0.15 })
  }

  function onLeave() {
    setTransform('perspective(1000px) rotateX(0) rotateY(0) scale(1)')
    setShine(s => ({ ...s, opacity: 0 }))
  }

  return (
    <div ref={ref} onMouseMove={onMove} onMouseLeave={onLeave} style={{
      background: '#111', border: `1px solid ${card.color}30`,
      borderRadius: 16, padding: 28, cursor: 'default',
      transform, transition: 'transform 0.1s ease',
      position: 'relative', overflow: 'hidden', minWidth: 200,
    }}>
      <div style={{
        position: 'absolute', inset: 0, opacity: shine.opacity,
        background: `radial-gradient(circle at ${shine.x}% ${shine.y}%, white, transparent 60%)`,
        transition: 'opacity 0.3s', pointerEvents: 'none',
      }} />
      <div style={{ position: 'absolute', top: 0, left: 0, right: 0, height: 2, background: card.color }} />
      <div style={{ fontSize: 32, marginBottom: 12 }}>{card.icon}</div>
      <div style={{ color: card.color, fontSize: 28, fontWeight: 900, letterSpacing: '-1px' }}>{card.stat}</div>
      <div style={{ color: '#F5F5F0', fontSize: 15, fontWeight: 600, marginTop: 4 }}>{card.title}</div>
      <div style={{ color: '#555', fontSize: 12, marginTop: 2 }}>{card.subtitle}</div>
    </div>
  )
}

export default function HoverTiltCard() {
  return (
    <div style={{ display: 'flex', gap: 20, padding: 48, background: '#0A0A0A', flexWrap: 'wrap', justifyContent: 'center' }}>
      {cards.map(c => <TiltCard key={c.title} card={c} />)}
    </div>
  )
}

Component info

CategoryCards
Frameworkreact
TierFREE
Views0
Copies0

About

3D tilt card with perspective transform on mouse move, gradient shine effect

More from Cards

'use client';

import React, { useState, useEffect } from 'react';

interface StatsCardProps {
  label: string;
  value: number;
  trend: 'up' | 'down';
  percentageChange: number;
  sparklineData: number[];
}

const StatsCard: React.FC<StatsCardProp
StatsCard
Cards
import React from 'react';
import { useEffect, useState } from 'react';

interface NoisyCardProps {
  children: React.ReactNode;
  className?: string;
}

const NoisyCard: React.FC<NoisyCardProps> = ({ children, className }) => {
  const [noise, setNo
NoisyCard
Cards
import React, { useState, useEffect } from 'react';

interface HolographicCardProps {
  children: React.ReactNode;
}

const HolographicCard: React.FC<HolographicCardProps> = ({ children }) => {
  const [mousePosition, setMousePosition] = useState({ x
HolographicCard
Cards
'use client';

import React, { useState } from 'react';

interface Notification {
  id: number;
  avatar: string;
  message: string;
  time: string;
  unread: boolean;
}

const notifications: Notification[] = [
  { id: 1, avatar: 'https://via.placeho
NotificationCard
Cards