-
Notifications
You must be signed in to change notification settings - Fork 0
Section 5: while( ) & for( )
Similar to if()
, while()
will also provide a conditional check against a logic condition. The difference is that with if()
the check only happens as the code passes by the if statement in our draw loop, and excecutes whatever happens in that code block or whatever is in the else block depending on which conditions are met. Afterward, it continues on through the code that comes after those blocks if there is any, and eventually when it reaches the end of the draw()
loop it starts over at the beginning of the draw()
loop.
On the otherhand with while()
, as long as the condition that we are checking are met, a while()
loop will continue indefinitely, preventing any code outside of the scope of the while()
block from excecuting. If the condition never changes, the program can be trapped forever. Sometimes you want this, but it can be a very serious pitfall.
while(condition){
do something until the condition is no longer met
}
An simple program with example of using while()
in a way that is problematic:
function setup(){
}
function draw() {
let my_condition = false;
let my_counter = 0;
while(my_condition != true){
my_counter = my_counter + 1; //as long as my_condition is false
console.log(my_counter);
}
if (my_counter > 20000){
my_condition = true;
}
}
So problematic it could even crash your browser window. The problem with this code is that despite the fact that the variable my_counter
will keep incrementing, the program will never leave the while loop, and the logical test that we have on the next line to check if my_counter
is greater than 20,000 will never be excecuted – thus leaving our poor variable my_counter to increment indefinitely until it runs out of memory and the browser crashes. A while loop that has no condition causing it to exit will run forever. Sort of like draw()
.
The same code with the if()
statement inside the while()
loop, will work however because our conditional check happens during our while condition.
function setup(){
}
function draw() {
let my_condition = false;
let my_counter = 0;
while(my_condition != true){
my_counter = my_counter + 1;
console.log(my_counter);
if (my_counter > 20000){
my_condition = true;
}
}
}
Sometimes, you just need to do something more than once, but only n
number of times. Similar, but more commonly used than while()
is the iterative for()
loop. This is where programming really starts to get interesting. Unlike the potentially infinite while()
loop, the for()
loop takes a set of THREE parameters that allow us finite control over how many times it runs. Each time it runs we also have a magical number that we can use if we want to (or not – totally optional).
| declare variable | conditional min or max | delta operation | description
|-----------|----------|------------|-----------------|---|
|(let i = 0;
| i < 10;
|i++;)
|will iterate over i while i is less than 10 |
|(let i = 10;
| i > 0;
|i--;)
|will iterate over i while i is less than 10 |
|(let i = 5;
| i < my_array.length;
|i+=3;)
|will iterate over every third element in an array called: my_array
beginning with element number 5 |
Note that unlike the code we've written so far, there are semicolons at the end of each parameter in the parenthesis in the for loop. These are three specific parameters that are excecuted like instructions that are necessary for a for loop to get initialized.
for(let i = 0; i < 10; i++){
console.log(i);
}
The above for loop will run exactly 10 times and then exit. Let's take a look at what is happening.
Inside the parenthesis where we give for
our parameters, we are declaring a new variable, (in this case i
, but it could be called anything), and i gets the value of zero. Then, in some slightly more confusing syntax, we check if i is less than 10 and if it is, we + 1
to the value of i
. This is sort of like an if statement with a built in counter that exits when it is reaches a maximum.
for(let i = 10; i > 0; i--){
console.log(i);
}
We can also start with any number, check against any number and use any math operator in the iterator.
for(var i = 100; i >= 0; i-=2){
console.log(i);
}
for(var i = 1; i < 2187; i*=3){
console.log(i);
}
output
var canvas; // declare canvas globally so you can use it everywhere
function setup() {
canvas = createCanvas(windowWidth, windowHeight);
//these features require the DOM Library which are added to the index.html file
canvas.position(0,0); // put the canvas at the top
canvas.style('z-index', '-1'); // put it behind the page content
}
function draw() {
background(100, 30);
let x;
let y;
let size;
for (let i = 0; i < 100; i++){
x = random(0, width);
y = random(0, height);
size = random(20, 30);
// draw 100 a randomly sized ellipses
// randomly placed on the canvas
ellipse(x, y, size, size);
}
//noLoop();
}
Since we are using our for loop inside of our draw loop, it means that we will be drawing 100 ellipses per frame. This took 6 lines of code, whereas without a for loop, this would take us roughly 400 lines of code to accomplish.
In the for loop from this example:
function draw() {
background(50, 8);
let distance = 30; // <-- try changing this
let r = random(100)+155;
let g = random(100)+155;
let b = random(100)+155;
for (let x = distance; x < width; x+=distance){
fill(r,g,b);
ellipse(x, distance/2, distance/2, distance/2);
}
}
We use our for loop it to calculate the distance between 0 and the width of our canvas, and then iterate over the loop using an external variable distance
. We use distance and x together to draw the ellipse and this will give us perfectly ordered and evenly spaced elipses. For fun we're generating a new color each frame, but setting all of our ellipses to the same color. From here, the options are endless, we could try to make our collection of ellipses follow our mouse in certain ways - like a rake for an electric zen garden, or...
Here we throw in a few bells and whistles, we us translate()
to move our row of for loop generated circles to the middle of the canvas, we employ the use of scale()
it shrink the whole context down to half the size, and then rotate the whole thing each frame. This also adds some conditional logic at the end to shift the whole thing one direction or the other based on some logic. The whole drama will take a few minutes to play out.
var canvas; // declare canvas globally so you can use it everywhere
var counter = 0;
var direction = true;
function setup() {
canvas = createCanvas(windowWidth, windowHeight);
//these features require the DOM Library which are added to the index.html file
canvas.position(0,0); // put the canvas at the top
canvas.style('z-index', '-1'); // put it behind the page content
}
function draw() {
background(50, 8);
let distance = 30; // <-- try changing this
translate(width/2, height/2);
scale(0.5); // <--try changing this
rotate(frameCount * 0.1); // <-- try multiplying frameCount by bigger numbers here
let r = random(100)+155;
let g = random(100)+155;
let b = random(100)+155;
for (let x = distance; x < width; x+=distance){
fill(r,g,b);
ellipse(x+counter, distance/2, distance/2, distance/2);
}
if (direction == true && counter >= -width){
counter--;
}else if(counter <= width){
counter++;
direction = false;
}
}
Taking for()
loops a step further, we can add dimension by nesting for loops inside of other for loops. In the example below, we take the previous example of drawing a row of ellipse()
we can also do something similar to make columns.
var canvas; // declare canvas globally so you can use it everywhere
function setup() {
canvas = createCanvas(windowWidth, windowHeight);
//these features require the DOM Library which are added to the index.html file
canvas.position(0,0); // put the canvas at the top
canvas.style('z-index', '-1'); // put it behind the page content
}
function draw() {
background(100, 10);
let distance = 80;
for (let x = distance; x < width; x+=distance){
for (let y = distance; y < height; y+=distance){
ellipse(x, y, distance/2, distance/2);
}
}
//noLoop();
}