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 */}
{/* 5. Centered Transport Controls */}
{/* Centered Song Title */}
{/* Centered Artist Name */}
{/* 4. Hand-Drawn Progress Bar & Timestamps */}
I Wanna be Yours
{/* Hand-Drawn Red Heart Icon */} setIsLiked(!isLiked)} className="ml-0.5">
Arctic Monkeys


Comments
Post a Comment