JS exercise 7 – Square Loops

This exercise aims to demonstrate the usefulness of “for loops” to execute repetitive tasks. The objective of the exercise is to create a gradient out of dozens of uniformly colored squares, which change color depending on cursor position. This is the code for the exercise:

<!DOCTYPE html>
<html>
<head>
	<title>Square Loops</title>
	<script type="text/javascript">
	var ctx, canvas;
	var mouseX, mouseY;
	var mouseColor;
	function setup(){
		mouseColor=0;
		canvas=document.getElementById("myCanvas");
		ctx=canvas.getContext("2d");
		canvas.addEventListener("mousemove",checkMouse);
		setInterval(draw,10);
	}
	function draw(){
		var nSquares = 10;
		//i will count through the columns
		for(var i=0;i<nSquares;	i++){
		//j will count through the rows
			for(var j=0;j<nSquares;	j++){
				var rChannel=Math.round(mouseColor);
				var gChannel=Math.round(i/nSquares*255);
				var bChannel=Math.round(j/nSquares*255);
				ctx.fillStyle="rgb("+rChannel+","+gChannel+","+bChannel+")";
				var x=i/nSquares*canvas.width;
				var y=j/nSquares*canvas.height;
				var w=canvas.width/nSquares;
				var h=canvas.height/nSquares;
				ctx.fillRect(x,y,w,h);
			}
		}
	}
	function checkMouse(evt){
		mouseX = evt.pageX-canvas.offsetLeft;
		mouseY = evt.pageY-canvas.offsetTop;
		mouseColor=(mouseX+mouseY)/(canvas.width+canvas.height)*255;
	}
	</script>
</head>
<body onload="setup()">
	<canvas id="myCanvas" width="400" height="400" style="border:1px solid">
	</canvas>
</body>
</html>

Most of the code is familiar to us by now, so I will focus on what is going on inside the for loops.

First, we created a for loop to distribute 10 squares (as defined in variable nSquares) on the horizontal axis:

for(var i=0;i<nSquares;	i++){
	var gChannel=Math.round(i/nSquares*255);
	ctx.fillStyle="rgb(255,"+gChannel+",0)";
	var x=i/nSquares*canvas.width;
	var w=canvas.width/nSquares;
	var h=canvas.height/nSquares;
	ctx.fillRect(x,0,w,h);
}

The for loop is structured as follows:

(variable=initialValue; test; increment)

Being that usually the test is something such as:

variable<endValue or variable<=endValue

In this case, we are dividing the canvas in 10 “slices” or columns, the first one being 0, and the last one being 9. Hence i=0, and i<nSquares (which has value 10). The increment is the unit: i++ (or i+=1, or i=i+1):

for(var i=0;i<nSquares;	i++){

Each square is progressively “yellower” – the gChannel variable stores a value which establishes a percentage between the current “slice” (i) and the total “slices” (10), and multiplies that by the maximum color value (255). The result is then rounded, and fed into the fillStyle:

	var gChannel=Math.round(i/nSquares*255);
	ctx.fillStyle="rgb(255,"+gChannel+",0)";

The x variable determines the position of each square. The formula creates a percentage between the current “slice” or column (i) and the total “slices” (10), and multiplies that by the maximum width (canvas.width):

	var x=i/nSquares*canvas.width;

The width and height of each square is 1/10 of the canvas width and height:

	var w=canvas.width/nSquares;
	var h=canvas.height/nSquares;

Then each square is drawn:

	ctx.fillRect(x,0,w,h);

Resulting in one row:

To draw the remaining rows, we added another for loop that works similarly:

for(var j=0;j<nSquares;	j++){

A bChannel variable was created, in analogy with gChannel, and the fillStyle was updated:

	var bChannel=Math.round(j/nSquares*255);
	ctx.fillStyle="rgb(255,"+gChannel+","+bChannel+")";

We could now distribute the squares in the vertical “slices” or columns, in analogy to the horizontal ones:

	var y=j/nSquares*canvas.height;

And we updated the fillRect method:

	ctx.fillRect(x,y,w,h);

Finally, we add a “checkMouse” function that aggregates the x and y positions (defined by “mouseX” and “mouseY” variables), and establishes a percentage between this aggregate and the aggregate width+height of the canvas. This percentage is then multiplied by the maximum color value (255) and stored in a mouseColor variable:

	mouseColor=(mouseX+mouseY)/(canvas.width+canvas.height)*255;

The mouseColor variable is then rounded and stored in a rChannel variable:

	var rChannel=Math.round(mouseColor);

This allows us to update the fillStyle, which will now change depending on the mouse position:

	ctx.fillStyle="rgb("+rChannel+","+gChannel+","+bChannel+")";

This is a screenshot of the resulting applet:

More on for loops in JavaScript:
http://www.w3schools.com/js/js_loop_for.asp
http://www.javascriptkit.com/jsref/looping.shtml

Link to the exercise: http://mlab.taik.fi/mediacode/coursefiles/course_2011_10/7-square_loops.html

Advertisements

1 thought on “JS exercise 7 – Square Loops

  1. Pingback: HTML 5 Canvas: “For” Loop and Square Gradient « Valeria's blog

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s