《JavaScript》Canvasで滑らかな波アニメーションをつくる
公開日:2025年05月22日 最終更新日:2025年5月22日
Canvasを使って、前後に重なる2つの波がランダムに流れるアニメーションを実装します。
DEMO
HTML
<div class="wave">
<canvas class="wave-canvas"></canvas>
</div>
CSS
.wave {
overflow: hidden;
width: 100%;
}
.wave-canvas {
display: block;
height: 200px;
width: 100%;
}
JavaScript
waveConfig内を変更すると波の速度や色を変更できます。
const waveConfig = {
colorFront: 'rgba(207, 87, 71, 0.8)', // 波の色(前)
colorBack: 'rgba(207, 87, 71, 0.4)', // 波の色(後)
amplitude: [15, 20], // 波の高さ(前・後)
frequency: [0.015, 0.01], // 波の細かさ(前・後)
speed: [0.5, 2], // 速さ(前・後)
height: 200,
direction: +1 // +1: 右から左, -1: 左から右
};
const canvas = document.querySelector('.wave-canvas');
const ctx = canvas.getContext('2d');
let width, height;
function resize() {
width = canvas.width = window.innerWidth;
height = canvas.height = waveConfig.height;
}
window.addEventListener('resize', resize);
resize();
let timeFront = 0;
let timeBack = 0;
function drawWaveLayer(freq, amp, color, time, direction) {
ctx.beginPath();
ctx.moveTo(0, height);
for (let x = 0; x <= width; x += 1) {
const phase = x - direction * time;
const y = height / 2 + Math.sin(phase * freq) * amp;
ctx.lineTo(x, y);
}
ctx.lineTo(width, height);
ctx.closePath();
ctx.fillStyle = color;
ctx.fill();
}
function animate() {
ctx.clearRect(0, 0, width, height);
drawWaveLayer(
waveConfig.frequency[1],
waveConfig.amplitude[1],
waveConfig.colorBack,
timeBack,
waveConfig.direction
);
drawWaveLayer(
waveConfig.frequency[0],
waveConfig.amplitude[0],
waveConfig.colorFront,
timeFront,
waveConfig.direction
);
timeFront += waveConfig.speed[0];
timeBack += waveConfig.speed[1];
requestAnimationFrame(animate);
}
animate();