import React, { useState, useEffect, useRef, useCallback } from 'react'; import { SVGFilters } from './components/SVGFilters.tsx'; import { RibbonSticker } from './components/RibbonSticker.tsx'; import { HandDrawnFrame } from './components/HandDrawnFrame.tsx'; import { EmbroideryWaveform } from './components/EmbroideryWaveform.tsx'; import { HandDrawnHeart } from './components/HandDrawnHeart.tsx'; import { HandDrawnProgressBar } from './components/HandDrawnProgressBar.tsx'; import { HandDrawnControls } from './components/HandDrawnControls.tsx'; import { soundEngine } from './utils/soundSynthesizer.ts'; export default function App() { const [isPlaying, setIsPlaying] = useState(false); const [currentTime, setCurrentTime] = useState(71); // Default ~1:11 as seen in photo const duration = 183; // 3:03 in seconds const [isLiked, setIsLiked] = useState(false); const [isShuffle, setIsShuffle] = useState(false); const [isRepeat, setIsRepeat] = useState(false); const [seed, setSeed] = useState(42); // 3D Card Interactive Tilt const cardRef = useRef(null); const [transformStyle, setTransformStyle] = useState('rotateX(0deg) rotateY(0deg)'); // Timer loop for audio playback useEffect(() => { let interval: number; if (isPlaying) { soundEngine.play(); interval = window.setInterval(() => { setCurrentTime((prev) => { if (prev >= duration) { if (isRepeat) { return 0; } else { setIsPlaying(false); soundEngine.pause(); return 0; } } return prev + 1; }); }, 1000); } else { soundEngine.pause(); } return () => { clearInterval(interval); soundEngine.pause(); }; }, [isPlaying, duration, isRepeat]); const handleTogglePlay = () => { setIsPlaying((prev) => !prev); }; const handleSeek = (newTime: number) => { setCurrentTime(Math.min(duration, Math.max(0, Math.floor(newTime)))); }; const handlePrev = () => { setCurrentTime(0); }; const handleNext = () => { setCurrentTime(0); setSeed((s) => s + 1); }; const handleToggleShuffle = () => { setIsShuffle((prev) => !prev); setSeed((s) => (s + 7) % 100); }; const handleToggleRepeat = () => { setIsRepeat((prev) => !prev); }; // Card 3D tilt tracking for organic tactile feel const handleMouseMove = useCallback((e: React.MouseEvent) => { if (!cardRef.current) return; const rect = cardRef.current.getBoundingClientRect(); const x = e.clientX - rect.left - rect.width / 2; const y = e.clientY - rect.top - rect.height / 2; const rotX = -(y / (rect.height / 2)) * 6; const rotY = (x / (rect.width / 2)) * 6; setTransformStyle(`perspective(1000px) rotateX(${rotX.toFixed(2)}deg) rotateY(${rotY.toFixed(2)}deg) scale3d(1.01, 1.01, 1.01)`); }, []); const handleMouseLeave = useCallback(() => { setTransformStyle('perspective(1000px) rotateX(0deg) rotateY(0deg) scale3d(1, 1, 1)'); }, []); return (
{/* SVG Global Filters */} {/* Background Soft Studio Lighting Glow */}
{/* Polaroid Card Outer Wrapper */}
{/* Paper Grain Overlay using SVG Filter */}
{/* Paper Deckle / Edge Highlights */}
{/* 1. Ribbon/Bow Sticker (Top Right Corner, ~15 degree rotated) */} {/* 2. 1:1 Square Hand-Drawn Frame with Embroidery Waveform */}
{/* 3. Song Details & Red Heart */}
{/* Centered Song Title */}

I Wanna be Yours

{/* Hand-Drawn Red Heart Icon */}
setIsLiked(!isLiked)} className="ml-0.5">
{/* Centered Artist Name */}

Arctic Monkeys

{/* 4. Hand-Drawn Progress Bar & Timestamps */}
{/* 5. Centered Transport Controls */}
); }

Comments

Popular Posts