import React from 'react'; /** Props for RenderLoading component */ interface RenderLoadingProps { /** Size of the vinyl record */ recordSize?: string; /** Apple silver light color for metallic effect */ appleSilverLight?: string; /** Apple silver main color */ appleSilverMain?: string; /** Apple silver dark color for shadows */ appleSilverDark?: string; /** Core gradient start color (cyan) */ coreGradientStart?: string; /** Core gradient middle color (purple) */ coreGradientMid?: string; /** Core gradient end color (magenta) */ coreGradientEnd?: string; /** Core glow color effect */ coreGlowColor?: string; /** Scanner light color */ scannerColor?: string; /** Record background color */ recordBg?: string; /** Overall background color */ backgroundColor?: string; /** Loading text */ loadingText?: string; /** Failed state trigger */ isFailed?: boolean; } /** * Vinyl record loading animation component with pulsing core and tonearm * @param props - Component configuration props * @returns React component with animated vinyl record loader */ const RenderLoading: React.FC = ({ recordSize = '250px', appleSilverLight = '#E5E5EA', appleSilverMain = '#D1D1D6', appleSilverDark = '#8A8A8E', coreGradientStart = '#00E4E4', coreGradientMid = '#8A2BE2', coreGradientEnd = '#FF00FF', coreGlowColor = 'rgba(138, 43, 226, 0.9)', scannerColor = 'rgba(0, 228, 228, 0.35)', recordBg = '#1A1A1A', backgroundColor = '#000', loadingText = 'Generating...', isFailed = false, }) => { /** Dead metal color for failed state */ const deadMetalColor = '#3A3A3A'; const styles = ` @keyframes rotateRecord { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } @keyframes rotateScanner { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } @keyframes placeTonearm { from { transform: rotate(-30deg); } to { transform: rotate(0deg); } } @keyframes bobTonearm { 0%, 100% { transform: rotate(0deg) translateY(0); } 25% { transform: rotate(0.5deg) translateY(2px); } 75% { transform: rotate(-0.5deg) translateY(-2px); } } @keyframes retractTonearm { from { transform: rotate(0deg); } to { transform: rotate(-30deg); } } @keyframes breakTonearm { 0% { transform: rotate(0deg); animation-timing-function: cubic-bezier(0.3, 0, 0.8, 0.7); /* 加速下坠 */ } 60% { transform: rotate(-55deg); /* 过冲到最大角度 */ animation-timing-function: cubic-bezier(0.1, 0.3, 0.4, 1.5); /* 回弹 */ } 100% { transform: rotate(-90deg); /* 稳定在最终角度 */ } } @keyframes pulse { 0%, 100% { transform: scale(1); box-shadow: 0 0 15px 6px ${coreGlowColor}, inset 0 0 4px 1px rgba(255,255,255,0.4); opacity: 0.9; } 50% { transform: scale(1.4); box-shadow: 0 0 35px 15px ${coreGlowColor}, inset 0 0 8px 3px rgba(255,255,255,0.7); opacity: 1; } } `; return ( <>
{/* Vinyl Record Container */}
{/* Record Half - Top */}
{/* Record grooves effect */}
{/* Scanner light */}
{/* Center label */}
{/* Pulsing core */}
{/* Record Half - Bottom */}
{/* Record grooves effect */}
{/* Scanner light */}
{/* Center label */}
{/* Pulsing core */}
{/* Tonearm */}
{/* Arm */}
{/* Head */}
{/* Pivot */}
{/* 加载/失败文案 */}
{loadingText}
); }; export default RenderLoading;