DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’»

Cover image for How to make a JavaScript canvas double line animation
Brett Anda πŸ”₯🧠 for Developer Bacon πŸ₯“πŸ₯“

Posted on • Originally published at developerbacon.ca on

How to make a JavaScript canvas double line animation

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");
Enter fullscreen mode Exit fullscreen mode

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");
Enter fullscreen mode Exit fullscreen mode

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 = [];
}
Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

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);
Enter fullscreen mode Exit fullscreen mode

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);
Enter fullscreen mode Exit fullscreen mode

Top comments (0)

Find what you were looking for? Join hundreds of thousands of developers on DEV so you can:

Β 
🌚 Enable dark mode
πŸ”  Change your default font
πŸ“š Adjust your experience level to see more relevant content