"use client"; import React, { useRef, useEffect } from "react"; interface ThreeDPerspectiveCardProps { /** The URL for the background image of the card. */ image: string; /** Optional width of the card (e.g., "300px"). Defaults to "300px". */ width?: string; /** Optional height of the card (e.g., "350px"). Defaults to "350px". */ height?: string; } const ThreeDPerspectiveCard: React.FC = ({ image, width = "300px", height = "350px", }) => { const cardRef = useRef(null); const shineRef = useRef(null); const shadowRef = useRef(null); useEffect(() => { // This is an optimization: the mouse move listener should only be // added if the client is ready and references exist. if (!cardRef.current || !shineRef.current || !shadowRef.current) { return; } const handleMouseMove = (event: MouseEvent) => { // Get window dimensions const wHeight = window.innerHeight; const wWidth = window.innerWidth; const currentMousePos = { x: event.pageX, y: event.pageY }; const mouseFromCenter = { x: currentMousePos.x - wWidth / 2, y: currentMousePos.y - wHeight / 2, }; // 1. Calculate Rotation for Card (3D Perspective) const maxRotation = 10; // Max rotation angle in degrees const mouseXRatio = (currentMousePos.x / wWidth) * 2 - 1; // Range from -1 to 1 const mouseYRatio = (currentMousePos.y / wHeight) * 2 - 1; // Range from -1 to 1 // around1 (RotateX) is inversely proportional to mouse Y const rotateXDeg = -1 * (mouseYRatio * maxRotation); // around2 (RotateY) is proportional to mouse X const rotateYDeg = mouseXRatio * maxRotation; // 2. Calculate Translation for Floating Effect const maxTranslate = 20; // Max translation in pixels const transX = mouseXRatio * maxTranslate; const transY = mouseYRatio * maxTranslate; // 3. Calculate Shine Angle (for linear-gradient) const dy = event.pageY - wHeight / 2; const dx = event.pageX - wWidth / 2; // Math.atan2 gives angle in radians, convert to degrees, and adjust const theta = Math.atan2(dy, dx); const angle = (theta * 180) / Math.PI - 90; // 4. Calculate Background Position (Parallax Effect) const backgroundPositionX = (currentMousePos.x / wWidth) * 100; // 0% to 100% const backgroundPositionY = (currentMousePos.y / wHeight) * 50; // 0% to 50% // Apply styles to Shine shineRef.current!.style.background = `linear-gradient(${angle}deg, rgba(255,255,255,${ (currentMousePos.y / wHeight) * 0.7 // Intensity based on Y position }) 0%, rgba(255,255,255, 0) 80%)`; // Apply styles to Card (3D Rotation, Float, and Parallax) cardRef.current!.style.transform = `translate3d(${transX}px, ${transY}px, 0) scale(1) rotateX(${rotateXDeg}deg) rotateY(${rotateYDeg}deg)`; cardRef.current!.style.backgroundPosition = `${backgroundPositionX}% ${backgroundPositionY}%`; // Apply styles to Shadow // This creates a subtle opposite movement and rotation for a deeper shadow effect shadowRef.current!.style.transform = `scale(.9,.9) translateX(${ mouseFromCenter.x * -0.02 + 12 }px) translateY(${mouseFromCenter.y * -0.02 + 12}px) rotateY(${ (mouseFromCenter.x / 25) * 0.5 }deg) rotateX(${mouseFromCenter.y / -25}deg)`; }; // Attach listener to the whole document document.addEventListener("mousemove", handleMouseMove); return () => document.removeEventListener("mousemove", handleMouseMove); }, []); // The rendering logic remains the same return (
{/* The styled-jsx block (THIS IS WHERE THE TS ERROR OCCURRED) */}
); }; export default ThreeDPerspectiveCard;