FLASH SALE Get 20% OFF everything using the coupon code: FLASH20 View WordPress Plugins →

JavaScript Canvas Sine Wave

on in Canvas
Last modified on

JavaScript Canvas Sine Wave

The code below generates a sine wave with a specified amplitude, frequency, and phase. The wave is drawn on the Canvas using the lineTo method, which creates a line from the current position to the specified x and y coordinates. The wave is redrawn on each frame of the animation using the requestAnimationFrame method, with the phase value incremented slightly to create the appearance of movement.

<canvas id="waveCanvas" width="600" height="400" style="width: 600px; height: 400px;"></canvas>
var canvas = document.getElementById("waveCanvas");
var ctx = canvas.getContext("2d");

var amplitude = 100;
var frequency = 0.05;
var phase = 0;

function drawWave() {
ctx.clearRect(0, 0, canvas.width, canvas.height);

ctx.beginPath();
ctx.moveTo(0, canvas.height / 2);

for(var x = 0; x < canvas.width; x++) {
    var y = amplitude * Math.sin(frequency * x + phase);
    ctx.lineTo(x, y + canvas.height / 2);
}

ctx.strokeStyle = "blue";
ctx.stroke();

phase += 0.05;

requestAnimationFrame(drawWave);
}

drawWave();

Next, I added an amplitude function. The amplitude value is incremented by a random value within a specified range, causing the wave to wiggle. I can now adjust the wiggleAmplitude value to control the strength of the wiggle effect.

var canvas = document.getElementById("waveCanvas");
var ctx = canvas.getContext("2d");

var amplitude = 100;
var frequency = 0.05;
var phase = 0;

var wiggleAmplitude = 5;

function drawWave() {
ctx.clearRect(0, 0, canvas.width, canvas.height);

ctx.beginPath();
ctx.moveTo(0, canvas.height / 2);

amplitude += Math.random() * wiggleAmplitude - wiggleAmplitude / 2;

for(var x = 0; x < canvas.width; x++) {
    var y = amplitude * Math.sin(frequency * x + phase);
    ctx.lineTo(x, y + canvas.height / 2);
}

ctx.strokeStyle = "blue";
ctx.stroke();

phase += 0.05;

requestAnimationFrame(drawWave);
}

drawWave();

Optionally, I can set the strokeStyle of the Canvas context to a random hexadecimal color value, so that the wave will be drawn in a different color on each frame of the animation. This creates a dynamic and colorful effect for the wave. I can adjust the range of the random color values to create different color palettes for the wave. I have not used the code below in my final code, as the result was too flickering.

ctx.strokeStyle = "#" + Math.floor(Math.random() * 16777215).toString(16);
ctx.stroke();

After messing with the variables and adding a bit more randomness, I got a nice, futuristic since wave.

var canvas = document.getElementById("waveCanvas");
var ctx = canvas.getContext("2d");

var amplitude = 10;
var frequency = 0.05;
var phase = 0;

var wiggleAmplitude = 5;

function drawWave() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);

    ctx.beginPath();
    ctx.moveTo(0, canvas.height / 2);

    amplitude += Math.random() * wiggleAmplitude - wiggleAmplitude / 2;

    var gradient = ctx.createLinearGradient(0, 0, canvas.width, 0);
    gradient.addColorStop(0, "#57076B");
    gradient.addColorStop(0.25, "#D058EE");
    gradient.addColorStop(0.5, "#C110EB");
    gradient.addColorStop(0.75, "#5E286B");
    gradient.addColorStop(1, "#950DB8");

    ctx.strokeStyle = gradient;

    for (var x = 0; x < canvas.width; x++) {
        var y = amplitude * Math.sin(frequency * x + phase);
        y += Math.random() * 10 - 5; // add random noise to y value
        var lineWidth = Math.random() * 10 + 1; // generate random line width between 1 and 11
        ctx.lineWidth = lineWidth;
        ctx.lineTo(x, y + canvas.height / 2);
    }

    ctx.fillStyle = "black";
    ctx.fillRect(0, 0, canvas.width, canvas.height);
    ctx.shadowColor = "#F6055D";
    ctx.shadowBlur = Math.random() * 72 + 1;
    ctx.shadowOffsetY = 8;

    ctx.stroke();

    phase += 0.05;

    requestAnimationFrame(drawWave);
}

drawWave();

See a demo below:

See the Pen JavaScript Canvas Sine Wave by Ciprian (@ciprian) on CodePen.

Related posts