'use client'; import React, { useState, useEffect, useMemo } from 'react'; export default function SciFiClock() { const [time, setTime] = useState(new Date()); const [frame, setFrame] = useState(0); // 动画循环 useEffect(() => { let animationFrameId; const animate = () => { setTime(new Date()); setFrame(f => f + 1); animationFrameId = requestAnimationFrame(animate); }; animationFrameId = requestAnimationFrame(animate); return () => cancelAnimationFrame(animationFrameId); }, []); // 计算时间角度 const ms = time.getMilliseconds(); const s = time.getSeconds(); const m = time.getMinutes(); const h = time.getHours(); // 平滑角度计算 const secondDeg = (s * 6) + (ms * 0.006); const minuteDeg = (m * 6) + (s * 0.1); const hourDeg = ((h % 12) * 30) + (m * 0.5); // 装饰性旋转角度 const ringRotate1 = frame * 0.2; const ringRotate2 = frame * -0.15; const pulse = Math.sin(frame * 0.05) * 0.5 + 0.5; // 0 to 1 // 格式化数字时间 const formatNum = (num) => num.toString().padStart(2, '0'); // 刻度生成 const ticks = useMemo(() => { return Array.from({ length: 60 }).map((_, i) => { const isHour = i % 5 === 0; const angle = (i * 6) * (Math.PI / 180); const radius = 180; const length = isHour ? 15 : 8; const x1 = Math.cos(angle) * radius; const y1 = Math.sin(angle) * radius; const x2 = Math.cos(angle) * (radius - length); const y2 = Math.sin(angle) * (radius - length); return { x1, y1, x2, y2, isHour, i }; }); }, []); return (
{/* 辉光滤镜 */} {/* 强辉光滤镜 */} {/* 渐变定义 */} {/* 背景网格线 */} {/* 动态背景数据装饰 */} SYS.UPTIME: {frame} COORDS: 400,300 RENDER: REACT_DOM MODE: AUTO {/* 主时钟容器 */} {/* 外部旋转装饰环 1 */} {/* 外部旋转装饰环 2 (反向) */} {/* 静态刻度盘 */} {ticks.map((t) => ( ))} {/* 数字刻度 */} {[12, 3, 6, 9].map((num, i) => { const a = i * 90 - 90; const rad = a * (Math.PI / 180); const r = 155; const x = Math.cos(rad) * r; const y = Math.sin(rad) * r; return ( {formatNum(num)} ); })} {/* 内部功能环 */} {/* 状态文字 */} 系统正常 SYNC MODE {/* 时针 (Hour Hand) */} {/* 分针 (Minute Hand) */} {/* 秒针 (Second Hand) */} {/* 中心装饰盖 (Center Cap) */} {/* 数字显示 HUD */} {formatNum(h)}:{formatNum(m)} {formatNum(s)} 本地时间 (LOCAL) {/* 左侧装饰信息 */} 能量等级 {Math.floor((s/60)*100)}%
); }