A double line animation starting from the left and proceeding to the right

How to make a JavaScript canvas double line animation

Updated | 4 min read

So you want to make a cool line drawing animation. Well, you have come to the right, and may be the 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 to not calculate those positions before every line is 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 lines 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.

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);