js实现海浪
使用Canvas绘制波浪动画
通过HTML5的Canvas API可以实现动态波浪效果。以下是一个基础实现示例:

const canvas = document.getElementById('waveCanvas');
const ctx = canvas.getContext('2d');
let time = 0;
function resizeCanvas() {
canvas.width = window.innerWidth;
canvas.height = 200;
}
resizeCanvas();
window.addEventListener('resize', resizeCanvas);
function drawWave() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.beginPath();
for (let x = 0; x < canvas.width; x++) {
const y = Math.sin(x * 0.02 + time) * 20 + canvas.height/2;
ctx.lineTo(x, y);
}
ctx.strokeStyle = '#3498db';
ctx.lineWidth = 2;
ctx.stroke();
time += 0.1;
requestAnimationFrame(drawWave);
}
drawWave();
添加渐变填充效果
增强视觉效果可以添加渐变填充:

function drawWaveWithFill() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.beginPath();
for (let x = 0; x <= canvas.width; x += 5) {
const y = Math.sin(x * 0.01 + time) * 30 + canvas.height/2;
if (x === 0) ctx.moveTo(x, y);
else ctx.lineTo(x, y);
}
ctx.lineTo(canvas.width, canvas.height);
ctx.lineTo(0, canvas.height);
ctx.closePath();
const gradient = ctx.createLinearGradient(0, 0, 0, canvas.height);
gradient.addColorStop(0, 'rgba(52, 152, 219, 0.8)');
gradient.addColorStop(1, 'rgba(52, 152, 219, 0.2)');
ctx.fillStyle = gradient;
ctx.fill();
time += 0.05;
requestAnimationFrame(drawWaveWithFill);
}
多图层波浪效果
创建更复杂的波浪可以叠加多个正弦波:
function drawMultiWave() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
// 第一层波浪
ctx.beginPath();
for (let x = 0; x < canvas.width; x++) {
const y = Math.sin(x * 0.01 + time) * 20
+ Math.sin(x * 0.02 + time * 0.7) * 10
+ canvas.height/2;
ctx.lineTo(x, y);
}
ctx.strokeStyle = 'rgba(52, 152, 219, 0.7)';
ctx.lineWidth = 2;
ctx.stroke();
// 第二层波浪
ctx.beginPath();
for (let x = 0; x < canvas.width; x++) {
const y = Math.sin(x * 0.015 + time * 1.2) * 15
+ Math.cos(x * 0.025 + time * 0.5) * 8
+ canvas.height/2 + 30;
ctx.lineTo(x, y);
}
ctx.strokeStyle = 'rgba(41, 128, 185, 0.5)';
ctx.stroke();
time += 0.03;
requestAnimationFrame(drawMultiWave);
}
使用WebGL实现3D波浪
对于高性能需求,可以使用Three.js创建3D波浪:
import * as THREE from 'three';
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
const geometry = new THREE.PlaneGeometry(20, 20, 100, 100);
const material = new THREE.MeshBasicMaterial({
color: 0x3498db,
wireframe: true,
side: THREE.DoubleSide
});
const plane = new THREE.Mesh(geometry, material);
scene.add(plane);
camera.position.z = 15;
function animate() {
requestAnimationFrame(animate);
for (let i = 0; i < plane.geometry.attributes.position.count; i++) {
const x = plane.geometry.attributes.position.getX(i);
const y = plane.geometry.attributes.position.getY(i);
const z = Math.sin(x + Date.now() * 0.001) * 0.5;
plane.geometry.attributes.position.setZ(i, z);
}
plane.geometry.attributes.position.needsUpdate = true;
renderer.render(scene, camera);
}
animate();
性能优化建议
- 对于复杂动画,使用
requestAnimationFrame而非setInterval - 避免在动画循环中创建新对象,尽量复用现有对象
- 对于静态背景元素,考虑使用CSS实现而非Canvas
- 在移动设备上适当降低动画帧率
- 使用Web Worker处理复杂计算
这些方法可以根据需求组合使用,创建从简单到复杂的各种波浪效果。实际应用中可以根据具体场景调整参数如振幅、频率和相位差来获得不同视觉效果。






