Canvas实现动态波浪时如何调整波形中间位置的上下偏移?
Canvas波浪效果对齐参考图修正方案

现有代码无法匹配参考效果的核心原因:
- 动画循环被注释:
animate函数内的requestAnimationFrame(animate)被注释,仅会渲染第一帧,无法产生连续流动效果 - 波浪路径闭合逻辑错误:绘制完波浪曲线后直接连接到离屏画布右上角,未先拉至画布右下角再闭合路径,导致填充区域偏移,波浪中线位置完全错位
- 绘制逻辑存在硬编码魔数:循环中
134、200、x/100等硬编码值未和画布宽度做映射,波浪密度、位置计算偏差 - 画布与渐变范围设置错误:离屏画布高度、渐变填充范围未匹配波浪振幅,导致顶部填充不全、底部漏空
修正后完整代码
HTML代码
<canvas id="wave"></canvas>
JavaScript代码
const canvas = document.getElementById('wave'); const ctx = canvas.getContext('2d'); const cw = window.innerWidth; const ch = window.innerHeight; canvas.width = cw; canvas.height = ch; let offsetX = 0; // 此处midWaveY设为屏幕高度75%位置,和参考图波浪中线对齐 const waveCanvas = makeWave(canvas.width, ch * 0.75, 60, 3, 'lightskyblue', 'cornflowerblue'); requestAnimationFrame(animate); function animate() { ctx.clearRect(0, 0, cw, ch); ctx.drawImage(waveCanvas, offsetX, 0); offsetX -= 1; if (offsetX < -waveCanvas.width / 2) { offsetX = 0; } // 恢复动画循环调用 requestAnimationFrame(animate); } function makeWave(width, midWaveY, amplitude, wavesPerWidth, grad0, grad1) { const PI2 = Math.PI * 2; const totalRadian = PI2 * wavesPerWidth; const offscreenCanvas = document.createElement('canvas'); const offscreenCtx = offscreenCanvas.getContext('2d'); // 离屏画布做2倍屏宽,保证无缝滚动 offscreenCanvas.width = width * 2; offscreenCanvas.height = midWaveY + amplitude; // 渐变覆盖整个填充区域 const grad = offscreenCtx.createLinearGradient(0, 0, 0, offscreenCanvas.height); grad.addColorStop(0, grad0); grad.addColorStop(1, grad1); offscreenCtx.beginPath(); offscreenCtx.moveTo(0, 0); // 逐像素绘制正弦波浪曲线 for (let x = 0; x <= offscreenCanvas.width; x++) { const rad = totalRadian * x / width; offscreenCtx.lineTo(x, Math.sin(rad) * amplitude + midWaveY); } // 正确闭合路径:波浪线终点→右下角→左下角→起点 offscreenCtx.lineTo(offscreenCanvas.width, offscreenCanvas.height); offscreenCtx.lineTo(0, offscreenCanvas.height); offscreenCtx.closePath(); offscreenCtx.fillStyle = grad; offscreenCtx.fill(); return offscreenCanvas; }
效果微调参数
如果需要调整波浪形态,直接修改对应参数即可:
midWaveY:控制波浪中线的垂直位置,数值越大波浪整体越靠下amplitude:控制波浪起伏高度,数值越大浪的高低差越大wavesPerWidth:控制单屏内的波浪数量,数值越大波浪越密集offsetX -= 1:控制波浪流动速度,数值越大流动越快
内容的提问来源于stack exchange,提问作者Adesh
相关产品推荐
相关产品推荐

