'use client'; import React, { useState, useEffect, useRef, useMemo } from 'react'; const VIEW_WIDTH = 1000; const VIEW_HEIGHT = 600; const CENTER_Y = VIEW_HEIGHT / 2; const CIRCLE_X = 150; const WAVE_START_X = 300; const RADIUS = 80; export const SineWaveView = () => { // 动画相位状态 const [phase, setPhase] = useState(0); const requestRef = useRef(); const previousTimeRef = useRef(); // 动画循环 const animate = (time: number) => { if (previousTimeRef.current !== undefined) { // 控制速度,每帧增加一点相位 setPhase(prev => (prev + 0.05) % (Math.PI * 2000)); // 防止数字过大溢出 } previousTimeRef.current = time; requestRef.current = requestAnimationFrame(animate); }; useEffect(() => { requestRef.current = requestAnimationFrame(animate); return () => { if (requestRef.current) cancelAnimationFrame(requestRef.current); }; }, []); // 计算当前圆上的点 (旋转点) // SVG坐标系Y轴向下,所以 sin 取反模拟常规数学坐标系视觉 const currentY = -Math.sin(phase) * RADIUS; const currentX = Math.cos(phase) * RADIUS; const circlePoint = { x: CIRCLE_X + currentX, y: CENTER_Y + currentY }; // 生成正弦波路径 // 公式: y = A * sin(wt - kx) // 这里我们需要波向右移动,即“向前延展”的视觉效果 const wavePath = useMemo(() => { let path = `M ${WAVE_START_X} ${CENTER_Y + currentY}`; // 绘制足够长的波形填满屏幕 const length = VIEW_WIDTH - WAVE_START_X - 50; for (let x = 0; x <= length; x += 2) { // x * 0.03 控制波长(频率) // phase 控制时间位移 const y = -Math.sin(phase - x * 0.03) * RADIUS; path += ` L ${WAVE_START_X + x} ${CENTER_Y + y}`; } return path; }, [phase, currentY]); return ( {/* 定义渐变色 */} {/* 发光滤镜 */} {/* 背景 */} {/* 标题 */} 正弦曲线生成原理 (Sine Wave Generation) {/* 坐标轴系统 */} {/* X轴 */} {/* Y轴 (圆心处) */} {/* Y轴 (波形开始处) */} {/* 标签文字 */} X (时间/位移) Y (振幅) {/* 左侧:单位圆部分 */} {/* 旋转半径线 */} {/* 角度弧线示意 */} Math.PI ? 1 : 0} 0 ${CIRCLE_X + Math.cos(-phase)*20} ${CENTER_Y + Math.sin(-phase)*20}`} fill="none" stroke="#fbbf24" strokeWidth="1" opacity="0.6" /> {/* 圆上的动点 */} {/* 连接线:从圆上的点到波形的起点 */} {/* 右侧:正弦波路径 */} {/* 波形起始点的追踪点 */} {/* 辅助信息面板 */} 公式: y = A · sin(ωt - kx) 状态: 正在生成波形... {/* 标注参数 */} A (振幅) ); };