canvas动态波形图关键在于时间精准:以performance.now()为唯一时间基准,用progress插值计算坐标(如正弦、缓动、多频叠加),全部逻辑置于requestanimationframe中,支持实时跳转校准。

Canvas 绘制动态平滑波形图,关键不在“画得快”,而在“画得准”——所有图形状态必须严格跟随真实时间轴变化,而不是靠帧数累加或定时器硬推。
用 performance.now() 建立统一时间基准
起始时间用 performance.now() 记录,后续每帧都用当前时间减去它,得到已过毫秒数。这个值就是你的唯一时间源,不依赖 setInterval 或 Date.now()(后者可能受系统时钟跳变影响)。外部时间源(如视频 currentTime、音频 playbackTime)也可直接接入,避免另起计时器造成漂移。
波形点坐标由 progress 插值得到
把总时长(比如 2000ms)作为分母,当前已过时间作为分子,算出 progress = Math.min(elapsed / duration, 1)。再把这个 progress 映射到波形函数中:
- 正弦波:y = centerY + amplitude * Math.sin(progress * Math.PI * 2 * frequency)
- 缓动波形:用 easeInOutCubic(progress) 替代线性 progress,让起伏更自然
- 多频叠加:可组合基频与谐波,如 y = base + harm1 * Math.sin(...) + harm2 * Math.cos(...)
requestAnimationFrame 是唯一可靠调度器
所有计算和绘制必须包裹在 requestAnimationFrame 回调里:
- 先更新 progress
- 再批量重算所有波形点坐标(避免逐点重复计算)
- 最后清空画布并重绘整条路径(不要只画增量段,否则易出现断点或残留)
不用 setTimeout/setInterval 模拟帧率——它们无法响应掉帧、节流或页面后台暂停,会导致波形拉伸或卡顿。
支持实时时间跳转与校准
当用户拖动时间滑块、点击某时刻或播放跳转时,不要重置计数器或强制插帧。应立刻用新时间重新计算 progress,并同步更新全部波形点位置。若波形依赖历史数据(如滚动显示),还需调整数据窗口偏移量,确保视觉连续性。











