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
相关产品推荐
相关产品推荐

