You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Canvas绘制夜间海洋实心波浪及效果优化问题求助

实心波浪实现方法

你当前的波浪路径已经是闭合状态(起点在左下角,沿波浪线绘制到右下角后回到左下角),不需要调整路径生成逻辑,核心修改只有三点:

  • 把路径绘制末尾的stroke()描边方法替换为fill()填充方法
  • 为不同层级的波浪设置区分度的填充色,替换原来统一的描边色
  • 把两个独立的requestAnimationFrame动画循环合并为一个,避免重复渲染造成的性能损耗,同时保留你原本调试好的波浪运动速度差
夜间场景优化建议

在保留原有波浪动态效果的基础上,可以做几处小调整提升真实感:

  • 按从远到近的顺序绘制3层波浪,越远的波浪颜色越深、运动速度越慢、起伏振幅越小,打造海面纵深感
  • 背景填充从上到下的藏蓝色渐变,替代纯色清空,模拟深夜天空到远海的色彩过渡
  • 给最靠近视角的浪峰加极淡的浅蓝半透明描边,模拟月光在浪尖的反光
  • 监听窗口resize事件动态更新画布尺寸,避免窗口缩放时画面变形
修改后完整可运行代码

JavaScript 逻辑

var c = document.getElementById("screen2");
var ctx = c.getContext("2d");
var cw = c.width = window.innerWidth;
var ch = c.height = window.innerHeight;
var w = window.innerWidth;
var h = 100;
var amplitude = h;
var frequency = .01;
var frames = 0;
const baseY = ch - 110;

// 分层波浪配置:从远到近
const waveLayers = [
  { color: "rgba(10, 25, 47, 0.9)", speed: 88, ampRatio: 0.3 },
  { color: "rgba(17, 34, 64, 0.85)", speed: 78, ampRatio: 0.4 },
  { color: "rgba(30, 58, 95, 0.8)", speed: 68, ampRatio: 0.5 }
]

// 窗口大小变化时重绘画布
window.addEventListener('resize', () => {
  cw = c.width = window.innerWidth;
  ch = c.height = window.innerHeight;
  w = window.innerWidth;
});

function draw() {
  frames++;
  ctx.clearRect(0, 0, cw, ch);

  // 绘制深夜海天渐变背景
  const bgGradient = ctx.createLinearGradient(0, 0, 0, ch);
  bgGradient.addColorStop(0, "#020c1b");
  bgGradient.addColorStop(0.6, "#0a192f");
  bgGradient.addColorStop(1, "#112240");
  ctx.fillStyle = bgGradient;
  ctx.fillRect(0, 0, cw, ch);

  // 逐层绘制实心波浪
  waveLayers.forEach((layer, index) => {
    const phi = frames / layer.speed;
    const currentAmp = amplitude * layer.ampRatio;
    ctx.beginPath();
    ctx.moveTo(0, ch);
    for (let x = 0; x < w; x++) {
      const y = Math.sin(x * frequency + phi) * currentAmp + currentAmp;
      ctx.lineTo(x, y + baseY);
    }
    ctx.lineTo(w, ch);
    ctx.lineTo(0, ch);
    ctx.closePath();
    ctx.fillStyle = layer.color;
    ctx.fill();

    // 最上层波浪添加浪尖高光
    if(index === waveLayers.length - 1) {
      ctx.strokeStyle = "rgba(210, 230, 255, 0.25)";
      ctx.lineWidth = 2;
      ctx.stroke();
    }
  })

  requestAnimationFrame(draw);
}
draw();

CSS 样式

* {
  margin: 0;
  padding: 0;
}
canvas {
  display: block;
  width: 100%;
  height: 100vh;
}

HTML 结构

<canvas id="screen2"></canvas>

内容的提问来源于stack exchange,提问作者vogellatte

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.02 05:24:53