diff --git a/src/components/FeaturedAlbums/AlbumCard3D.jsx b/src/components/FeaturedAlbums/AlbumCard3D.jsx new file mode 100644 index 0000000..83d3276 --- /dev/null +++ b/src/components/FeaturedAlbums/AlbumCard3D.jsx @@ -0,0 +1,94 @@ +import { useRef, useState } from 'react' +import { motion, useMotionValue, useSpring, useTransform } from 'framer-motion' + +export default function AlbumCard3D({ album, onPlay, isActive }) { + const cardRef = useRef() + const [hovered, setHovered] = useState(false) + const x = useMotionValue(0) + const y = useMotionValue(0) + const rotateX = useSpring(useTransform(y, [-0.5, 0.5], [14, -14]), { stiffness: 260, damping: 26 }) + const rotateY = useSpring(useTransform(x, [-0.5, 0.5], [-14, 14]), { stiffness: 260, damping: 26 }) + + const onMove = (e) => { + const r = cardRef.current.getBoundingClientRect() + x.set((e.clientX - r.left) / r.width - 0.5) + y.set((e.clientY - r.top) / r.height - 0.5) + } + const onLeave = () => { x.set(0); y.set(0); setHovered(false) } + + return ( + setHovered(true)} + onMouseLeave={onLeave} + style={{ rotateX, rotateY, transformStyle: 'preserve-3d', perspective: 900 }} + whileHover={{ scale: 1.04, y: -8 }} + transition={{ type: 'spring', stiffness: 280, damping: 24 }} + className="relative rounded-2xl overflow-hidden cursor-pointer group shadow-card" + onClick={() => onPlay(album)} + > + {/* Background */} +
+ + {/* Hover glow */} + + + {/* Active indicator */} + {isActive && ( +
+ + Playing +
+ )} + + {/* Cover art */} +
+ {album.title} +
+ + {/* Play overlay */} + + + + + + + +
+ + {/* Info */} +
+

{album.title}

+

{album.artist} ยท {album.year}

+
+ + {album.genre} + + {album.tracks} trk +
+
+ + ) +}