Skip to content

Instantly share code, notes, and snippets.

@costidima
Created August 3, 2020 18:13
Show Gist options
  • Save costidima/f5d29bce536b0d7951c06e0ce20c7515 to your computer and use it in GitHub Desktop.
Save costidima/f5d29bce536b0d7951c06e0ce20c7515 to your computer and use it in GitHub Desktop.
Animated SVG waves
<?xml version="1.0" standalone="no"?>
<svg width="100%" height="150" version="1.1" xmlns="http://www.w3.org/2000/svg" id="intro">
<path id="wave" d="" stroke="#000" fill="transparent" />
<path id="wave2" d="" stroke="#000" fill="transparent" />
<path id="wave3" d="" stroke="#000" fill="transparent" />
<path id="wave4" d="" stroke="#000" fill="transparent" />
<path id="wave5" d="" stroke="#000" fill="transparent" />
<path id="wave6" d="" stroke="#000" fill="transparent" />
<path id="wave7" d="" stroke="#000" fill="transparent" />
<path id="wave8" d="" stroke="#000" fill="transparent" />
</svg>
var container = document.body;
var width = container.offsetWidth;
var height = 200;
var wave = document.getElementById('wave');
var wave2 = document.getElementById('wave2');
var wave3 = document.getElementById('wave3');
var wave4 = document.getElementById('wave4');
var wave5 = document.getElementById('wave5');
var wave6 = document.getElementById('wave6');
var wave7 = document.getElementById('wave7');
var wave8 = document.getElementById('wave8');
var waveWidth = container.offsetWidth; // Wave SVG width (usually container width)
var waveHeight = 40; // Position from the top of container
var waveDelta = 20; // Wave amplitude
var speed = 0.5; // Wave animation speed
var wavePoints = 6; // How many point will be used to compute our wave
var points = [];
function calculateWavePoints(factor) {
var points = [];
for (var i = 0; i <= wavePoints; i++) {
var x = i/wavePoints * waveWidth;
var sinSeed = (factor + (i + i % wavePoints)) * speed * 100;
var sinHeight = Math.sin(sinSeed / 100) * waveDelta;
var yPos = Math.sin(sinSeed / 100) * sinHeight + waveHeight;
points.push({x: x, y: yPos});
}
return points;
}
function buildPath(points) {
var SVGString = 'M ' + points[0].x + ' ' + points[0].y;
var cp0 = {
x: (points[1].x - points[0].x) / 2,
y: (points[1].y - points[0].y) + points[0].y + (points[1].y - points[0].y)
};
SVGString += ' C ' + cp0.x + ' ' + cp0.y + ' ' + cp0.x + ' ' + cp0.y + ' ' + points[1].x + ' ' + points[1].y;
var prevCp = cp0;
var inverted = -1;
for (var i = 1; i < points.length-1; i++) {
var cpLength = Math.sqrt(prevCp.x * prevCp.x + prevCp.y * prevCp.y);
var cp1 = {
x: (points[i].x - prevCp.x) + points[i].x,
y: (points[i].y - prevCp.y) + points[i].y
};
SVGString += ' C ' + cp1.x + ' ' + cp1.y + ' ' + cp1.x + ' ' + cp1.y + ' ' + points[i+1].x + ' ' + points[i+1].y;
prevCp = cp1;
inverted = -inverted;
};
SVGString += ' L ' + width + ' ' + height;
SVGString += ' L 0 ' + height + ' Z';
return SVGString;
}
var lastUpdate;
var totalTime = 0;
function tick() {
var now = window.Date.now();
if (lastUpdate) {
var elapsed = (now-lastUpdate) / 1000;
lastUpdate = now;
totalTime += elapsed;
var factor = totalTime*Math.PI;
var _d = buildPath(calculateWavePoints(factor));
wave.setAttribute('d', _d);
wave2.setAttribute('d', _d);
wave3.setAttribute('d', _d);
wave4.setAttribute('d', _d);
wave5.setAttribute('d', _d);
wave6.setAttribute('d', _d);
wave7.setAttribute('d', _d);
wave8.setAttribute('d', _d);
} else {
lastUpdate = now;
}
window.requestAnimationFrame(tick);
};
tick();
html, body {
height: 100%;
}
#wave2 {
transform: translateY(5%);
}
#wave3 {
transform: translateY(10%);
}
#wave4 {
transform: translateY(15%);
}
#wave5 {
transform: translateY(20%);
}
#wave6 {
transform: translateY(25%);
}
#wave7 {
transform: translateY(30%);
}
#wave8 {
transform: translateY(35%);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment