Skip to content

Instantly share code, notes, and snippets.

@davidbwaters
Created July 23, 2020 12:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save davidbwaters/9d59fc87fccdb716c11ec1c683cb6c5e to your computer and use it in GitHub Desktop.
Save davidbwaters/9d59fc87fccdb716c11ec1c683cb6c5e to your computer and use it in GitHub Desktop.
Single line waveform formulas
canvas#canvas Your browser doesn't support the HTML5 Canvas element :(
((ctx, w, h) => {
const maxValue = h / 10;
const graphWidth = 200;
const graphHeight = maxValue;
let curY = h / 2 - graphHeight / 2;
let curX = 50;
let waves = [];
let tick = 0;
function Main() {
canvas.width = w;
canvas.height = h;
this.init();
}
Main.prototype = {
init: function() {
/**
* Initialize the waveforms and push them into 'waves'.
* The first argument is the display name,
* the second the function that takes 1 argument (i)
* which is the value to evaluate the function to.
*/
waves.push(new WaveForm(
'sawtooth',
i => i % maxValue
));
waves.push(new WaveForm(
'square',
i => (i % maxValue * 2 < maxValue) ? maxValue : 0
));
waves.push(new WaveForm(
'triangle',
i => Math.abs((i % (maxValue * 2)) - maxValue)
));
waves.push(new WaveForm(
'sine',
i => maxValue / 2 * Math.sin(i / 24.5) + maxValue / 2
// the divider ( / 24.5) is only added to spread the graph, you can leave it out or change the value to whatever you like
));
this.request = requestAnimationFrame(() => this.draw());
window.addEventListener('resize', () => this.resize());
},
draw: function() {
this.request = requestAnimationFrame(() => this.draw());
ctx.clearRect(0, 0, w, h);
tick++;
ctx.strokeStyle = 'white';
ctx.lineWidth = 3;
ctx.lineCap = 'round';
waves.forEach(wave => wave.draw(tick));
}
};
function WaveForm(name, fn) {
this.name = name;
this.fn = fn;
this.x = 50;
this.y = 50 + waves.length * (graphHeight + 50);
}
WaveForm.prototype = {
draw: function(currentTick) {
// plot the entire graph first
this.plotGraph();
// then draw a little circle at the head
this.drawPosition(currentTick + graphWidth);
// draw the title
ctx.font = 'Arial 18px';
ctx.fillStyle = 'white';
ctx.fillText(this.name, this.x, this.y - 20);
},
plotGraph: function() {
ctx.beginPath();
ctx.moveTo(this.x, this.y + this.fn(tick));
for(var i = 1; i < graphWidth; i++)
ctx.lineTo(this.x + i, this.y + this.fn(i + tick));
ctx.stroke();
ctx.closePath();
},
drawPosition: function(position) {
ctx.fillStyle = `hsla(0,0%,100%,${ Math.abs((tick / 100 % 2) - 1) + .25 })`;
ctx.beginPath();
ctx.arc(this.x + graphWidth, this.y + this.fn(position), 5, 0, Math.PI * 2);
ctx.closePath();
ctx.fill();
}
}
const main = new Main();
})(canvas.getContext('2d'), 300, 450);

Single line waveform formulas

Some default waveforms defined as a single line function

A Pen by Robert on CodePen.

License.

body { background: hsla(210,100%,20%,1) }
canvas {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment