波浪线背景特效(Canvas 正弦波浪线动画,参数全可调)
波浪线背景特效:多色正弦波浪线在画布上此起彼伏,振幅、频率、速度与线条数实时可调,每条线相位错开形成连绵动感,Canvas 自研适配高分屏。
效果演示(真实可交互)
多道彩色正弦波线条均匀分布在画布上,各自以错开的相位起伏流动,像风吹过水面荡起的层层波纹。四条滑杆分别控制振幅(5-80px,波峰高度)、频率(1-10,波形的疏密)、速度(1-20,相位推进速率)和线条数量(3-14 条)。每条线之间除了相位差(i * 0.8),透明度还叠加了一个独立的慢速正弦,因此线条会忽明忽暗地”呼吸”,层次感更强。实现思路非常朴素:对每个 x 采样点计算 y = baseY + sin(x·freq + phase)·amp,以 4px 步长连线成路径再描边,整段代码不足 60 行。
完整代码
<canvas id="waves" style="width:100%;height:340px;display:block;background:linear-gradient(180deg,#0b1026,#131a33);"></canvas>
const canvas = document.getElementById('waves');
const ctx = canvas.getContext('2d');
let W, H, phase = 0;
const cfg = { amp: 34, freq: 3, speed: 8, lines: 7 };
const PALETTE = ['#4f6ef7', '#22d3ee', '#a855f7', '#f472b6', '#34d399', '#f59e0b', '#60a5fa'];
function resize() {
const r = canvas.getBoundingClientRect();
const dpr = window.devicePixelRatio || 1;
canvas.width = Math.round(r.width * dpr);
canvas.height = Math.round(r.height * dpr);
ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
W = r.width; H = r.height;
}
function step() {
ctx.clearRect(0, 0, W, H);
const spacing = H / (cfg.lines + 1); // 均分垂直空间
phase += .02 * cfg.speed;
for (let i = 0; i < cfg.lines; i++) {
const baseY = spacing * (i + 1);
ctx.beginPath();
for (let x = 0; x <= W; x += 4) {
const y = baseY + Math.sin(x * .01 * cfg.freq + phase + i * .8) * cfg.amp;
x === 0 ? ctx.moveTo(x, y) : ctx.lineTo(x, y);
}
ctx.strokeStyle = PALETTE[i % PALETTE.length];
ctx.globalAlpha = .55 + .3 * Math.sin(phase * .5 + i); // 呼吸透明
ctx.lineWidth = 2;
ctx.stroke();
}
ctx.globalAlpha = 1;
requestAnimationFrame(step);
}
resize(); step();
window.addEventListener('resize', resize);
参数说明
| 参数 | 位置 | 说明 |
|---|---|---|
| 振幅 | cfg.amp | 5-80px,波峰到基线的距离 |
| 频率 | cfg.freq | 1-10,越大波形越密 |
| 速度 | cfg.speed | 1-20,相位推进速率,0.02 为单帧基数 |
| 线条数 | cfg.lines | 3-14,自动均分画布高度 |
| 相位差 | i * .8 | 各线错开的程度,0 则所有线同步 |
| 颜色 | PALETTE | 按线条序号循环取色,可换成渐变色 |
兼容性与性能
- 只使用基础 Canvas 2D(beginPath / lineTo / stroke),所有现代浏览器均支持。
- 已适配
devicePixelRatio,高分屏线条锐利;采样步长 4px 在普通宽度下每线约 200 个点,14 条线一帧约 2800 次 lineTo,开销极小。 - 若需要更粗的波浪,可把
lineWidth调大并配合globalAlpha做出层叠的半透明波纹。 - 想停掉”呼吸”效果,把
globalAlpha改回固定值即可,可减少一次正弦计算。 - 移动端建议线条数 ≤ 10,振幅 ≤ 50,确保低端机仍满帧。
常见问题
Q: 线条在画布边缘会露出”断头”吗? 会。正弦波的端点不一定在波峰,视觉上像被截断——这是正常现象。若要更完整,可让振幅在靠近左右边缘时衰减(乘以 Math.min(x, W-x)/W 之类的包络函数)。
Q: 想让波浪有立体填充效果? 把每条线闭合到底部:lineTo(x, H) 后 closePath() 并 fill(),用半透明色填充,就能做出层叠的山峦/波浪填充图。
Q: 波浪线适合做什么场景? 适合做音乐播放页、数据大屏、落地页头部装饰;配合文字放中间,用 position: relative; z-index: 1 即可叠在波浪上方。
Q: 为什么我的波浪看起来在抖动? 通常是因为步长过大(如 8px)配合高频率,正弦采样不足。把步长降到 2-3px,或降低频率即可消除锯齿抖动。
许可与来源
- 许可证:自研原创 —— 粤喵自研原创,可免费用于个人与商业项目,无需署名。查看来源公示与许可清单
- 来源:粤喵团队原创自研(从效果思路到代码实现均为独立完成,未直接复制第三方代码)
- 首次发布:2026-09-01 · 最近更新:2026-09-01
- 修改日志:2026-09-01 首次发布;2026-09-13 补充许可证与来源标注、复制按钮说明与法务页入口
- 纠错:联系页面 / min@cactus.asia,2 个工作日内核实处理
常见问题
这个组件可以商用吗?
可以。本组件为粤喵自研原创,可免费用于个人和商业项目,无需署名。
浏览器兼容性如何?
支持所有现代浏览器(Chrome / Firefox / Safari / Edge 最新版本)。旧版 IE 不支持 CSS 动画相关特性。
怎么修改动画参数?
直接调整 CSS 中的 animation-duration(时长)、animation-timing-function(缓动曲线)等属性即可,代码中有注释说明。