loading...
Cover image for How to make a JavaScript canvas double line animation
Developer Bacon 🥓🥓

How to make a JavaScript canvas double line animation

brettanda profile image Brett Anda 🔥🧠 Originally published at developerbacon.ca on ・4 min read

So you want to make a cool line drawing animation. Well, you have come to the right and maybe only place for this specific JavaScript canvas animation.

Canvas Context and definition

To get started we will need to define the context for the canvas element like so:

let context = document.getElementById("backface").getContext("2d");

For reference, the ID for the canvas element is backface.

Defining an element without setting a variable

Did you know that you don't have to set a variable for an element if that element already has an ID? You can just use that ID as the variable and JavaScript will grab that element. For example, if we use the example above without setting a variable for the canvas it would look like the below.

let context = backface.getContext("2d");

Variables

Before we start animating we will want some empty variables for the lines to add themselves to. I chose to add every line to a variable so the positions of the lines can be chosen before the animation begins as to not calculate those positions before every line drawn.

// The line width for every line
lineWidth = 5; // 5px

function lines() {
    let valuesT = [],
        valuesB = [];
}

Now that we have arrays for the top and bottom line we can add height values for each line to be drawn later. This for loop chooses a random value between the vertical center and 0 for the height of that line. Inside the above function, you will want to add the below code.

for (var i = 0; i < backface.width; i++) {
    valuesT[i] = Math.floor(Math.random() * (backface.height / 2 - 1)) + 1;
    valuesB[i] = Math.floor(Math.random() * (backface.height / 2 - 1)) + 1;
}

Let's get some color going into this animation.

var i = 0,
    rr = Math.floor(Math.random() * (3 - 1)) + 1,
    rg = Math.floor(Math.random() * (3 - 1)) + 1,
    rb = Math.floor(Math.random() * (3 - 1)) + 1,
    r = 255,
    g = 255,
    b = 255;

Now for the line drawing. First, we will call the function with a requestAnimationFrame, then the random color for the line will be chosen and finally, the line will be drawn.

requestAnimationFrame(() => drawLines(i));

function drawLines(i) {
    //change this to a for loop that works.
    if (rr == 2) {
        r = Math.floor(Math.random() * (255 - 1)) + 1;
    } else {
        r = 0;
    }
    if (rg == 2) {
        g = Math.floor(Math.random() * (255 - 1)) + 1;
    } else {
        g = 0;
    }
    if (rb == 2) {
        b = Math.floor(Math.random() * (255 - 1)) + 1;
    } else {
        b = 0;
    }
    if (rr != 2 && rg != 2 && rb != 2) {
        var rand = Math.floor(Math.random() * (255 - 1)) + 1;
        r = rand;
        g = rand;
        b = rand;
    }

    context.clearRect(i, 0, 1 + lineWidth, backface.height);
    context.beginPath();
    context.lineWidth = lineWidth;
    context.strokeStyle = `rgba(${r},${g},${b},1)`;
    context.moveTo(i, 0);
    context.lineTo(i, 0 + valuesT[i]);
    context.stroke();
    context.closePath();

    context.beginPath();
    context.lineWidth = lineWidth;
    context.strokeStyle = `rgba(${r},${g},${b},1)`;
    context.moveTo(i, backface.height);
    context.lineTo(i, backface.height - valuesB[i]);
    context.stroke();
    context.closePath();

    // This just loops through the function until the edge
    // of the canvas has been hit and will repeat.
    if (i >= backface.width) {
        i = 0;
        requestAnimationFrame(lines);
    } else {
        i = i + 1 + lineWidth;
        requestAnimationFrame(function() {
            drawLines(i);
        });
    }
}
requestAnimationFrame(lines);

Conclusion

Below is the CodePen example of the above code with the full code below the CodePen example.

See the Pen Vertical Lines Double Animated by Brett
(@brettanda) on CodePen.

let context = backface.getContext("2d"),
    lineWidth = 5;

function lines() {
    var valuesT = [],
        valuesB = [];
    for (var i = 0; i < backface.width; i++) {
        valuesT[i] = Math.floor(Math.random() * (backface.height / 2 - 1)) + 1;
        valuesB[i] = Math.floor(Math.random() * (backface.height / 2 - 1)) + 1;
    }
    var i = 0,
        rr = Math.floor(Math.random() * (3 - 1)) + 1,
        rg = Math.floor(Math.random() * (3 - 1)) + 1,
        rb = Math.floor(Math.random() * (3 - 1)) + 1,
        r = 255,
        g = 255,
        b = 255;
    requestAnimationFrame(() => drawLines(i));
    function drawLines(i) {
        //change this to a for loop that works.
        if (rr == 2) {
            r = Math.floor(Math.random() * (255 - 1)) + 1;
        } else {
            r = 0;
        }
        if (rg == 2) {
            g = Math.floor(Math.random() * (255 - 1)) + 1;
        } else {
            g = 0;
        }
        if (rb == 2) {
            b = Math.floor(Math.random() * (255 - 1)) + 1;
        } else {
            b = 0;
        }
        if (rr != 2 && rg != 2 && rb != 2) {
            var rand = Math.floor(Math.random() * (255 - 1)) + 1;
            r = rand;
            g = rand;
            b = rand;
        }

        context.clearRect(i, 0, 1 + lineWidth, backface.height);
        context.beginPath();
        context.lineWidth = lineWidth;
        context.strokeStyle = `rgba(${r},${g},${b},1)`;
        context.moveTo(i, 0);
        context.lineTo(i, 0 + valuesT[i]);
        context.stroke();
        context.closePath();

        context.beginPath();
        context.lineWidth = lineWidth;
        context.strokeStyle = `rgba(${r},${g},${b},1)`;
        context.moveTo(i, backface.height);
        context.lineTo(i, backface.height - valuesB[i]);
        context.stroke();
        context.closePath();

        if (i >= backface.width) {
            i = 0;
            requestAnimationFrame(lines);
        } else {
            i = i + 1 + lineWidth;
            requestAnimationFrame(function() {
                drawLines(i);
            });
        }
    }
}
requestAnimationFrame(lines);

Posted on by:

brettanda profile

Brett Anda 🔥🧠

@brettanda

I make tutorials for beginner developers at developerbacon.ca 🥓

Developer Bacon 🥓🥓

A website made with Gridsome aimed to help beginner web developers

Discussion

markdown guide