/** * OmniMotion — 悬浮卡片 / TiltCard (React 18+ · 指针跟随倾斜) * 复刻来源: unseen.co — 指针在卡片内移动时轻微 3D 倾斜 * 用法: ... */ import { useRef } from "react"; export default function TiltCard({ tilt = true, range = 2, children }) { const ref = useRef(null); function onMove(event) { if (!tilt || !ref.current) return; const rect = ref.current.getBoundingClientRect(); const x = (event.clientX - rect.left) / rect.width - 0.5; const y = (event.clientY - rect.top) / rect.height - 0.5; ref.current.style.transform = "perspective(600px) rotateY(" + x * range * 2 + "deg) rotateX(" + -y * range * 2 + "deg)"; } function onLeave() { if (ref.current) ref.current.style.transform = ""; } return (
{children}
); } /* 样式(可直接放入全局 CSS) .mk-tilt { display: flex; flex-direction: column; gap: 8px; width: 118px; padding: 14px 14px 16px; border-radius: 8px; background: var(--mk-stage-surface); border: 1px solid var(--mk-stage-line); transition: transform 240ms cubic-bezier(0.2, 0.8, 0.2, 1); animation: mk-tilt 4s cubic-bezier(0.3, 0, 0, 1) infinite; } @keyframes mk-tilt { 0%, 100% { transform: translateY(-6px) rotate(-2deg); } 50% { transform: translateY(6px) rotate(2deg); } } @media (prefers-reduced-motion: reduce) { .mk-tilt { animation: none } } */