import { Card, CardProps } from '@heroui/card'; import clsx from 'clsx'; import React from 'react'; export interface HoverEffectCardProps extends CardProps { children: React.ReactNode maxXRotation?: number maxYRotation?: number lightClassName?: string lightStyle?: React.CSSProperties } const HoverEffectCard: React.FC = (props) => { const { children, maxXRotation = 5, maxYRotation = 5, className, style, lightClassName, lightStyle, } = props; const cardRef = React.useRef(null); const lightRef = React.useRef(null); const [isShowLight, setIsShowLight] = React.useState(false); const [pos, setPos] = React.useState({ left: 0, top: 0, }); return ( { if (cardRef.current) { cardRef.current.style.transition = 'transform 0.3s ease-out'; } }} onMouseLeave={() => { setIsShowLight(false); if (cardRef.current) { cardRef.current.style.transition = 'transform 0.5s'; cardRef.current.style.transform = 'perspective(1000px) rotateX(0deg) rotateY(0deg) scale3d(1, 1, 1)'; } }} onMouseMove={(e: React.MouseEvent) => { if (cardRef.current) { setIsShowLight(true); const { x, y } = cardRef.current.getBoundingClientRect(); const { clientX, clientY } = e; const offsetX = clientX - x; const offsetY = clientY - y; const lightWidth = lightStyle?.width?.toString() || '100'; const lightHeight = lightStyle?.height?.toString() || '100'; const lightWidthNum = parseInt(lightWidth); const lightHeightNum = parseInt(lightHeight); const left = offsetX - lightWidthNum / 2; const top = offsetY - lightHeightNum / 2; setPos({ left, top, }); cardRef.current.style.transition = 'transform 0.1s'; const rangeX = 400 / 2; const rangeY = 400 / 2; const rotateX = ((offsetY - rangeY) / rangeY) * maxXRotation; const rotateY = -1 * ((offsetX - rangeX) / rangeX) * maxYRotation; cardRef.current.style.transform = `perspective(1000px) rotateX(${rotateX}deg) rotateY(${rotateY}deg)`; } }} >
{children} ); }; export default HoverEffectCard;