This tutorial will show how to use an array to store a list of values, that represent shapes.
We'll start by working in direct mode, where drawing happens directly to the canvas. The canvas "remembers" what is drawn by recording what color is at each pixel (just like a real canvas uses paint to "remembers" what the brush did) , but the JavaScript code doesn't.
What if we use opaque paint, instead of semi-transparent paint.
We never see any circles!
This is because at the beginning of each frame, the entire canvas is painted white. This draws over whatever drawing happened inside of `mouseDragged`.
We'll fix this by switching from direct mode to retained mode, where the sketch remembers what to draw, so that it can draw it again after the canvas is erased.
This step replaces the two variables `shapeX` and `shapeY`, by a single variable that can store two values.
It does this by storing one value whose type is an Array.
To see how this works, use Python Tutor to step through this code. (The Python Tutor example pretends to be p5.js, by defining `ellipse` and by calling `mouseDragged` and `draw` just like p5.js does.)
In the next step, we will see why it's useful to package all the properties related to one of the shapes that is drawn on the canvas – currently, x and y – into a single Array.
Now we can do remove shapes from list.
`push` adds an element to the end of the array. `shift` removes the first element from the beginning of the array. I found it by reading through the Array instance methods in the developer documentation for JavaScript Array.
Previously, each shape was represented as a list [x, y]. Extend this to [shapeType, x, y], so that we can draw shapes other than ellipses.
This code has the same behavior as the previous step. We haven't actually added any other shape types yet. This follows the practice of prepare the code for extended behavior, see that we haven't broken anything, and then extend it.
Compare this step to the previous step.
Note that the code inside mousePressed is `shapeType = …`, not `let shapeType = `. The latter, with let, would create a local variable inside of mousePressed, and assign to that. This assignment wouldn't affect the global variable that is defined at the top of the file, so `mouseDragged` wouldn't see the value ('ellipse' or 'rect') that `mousePressed` selects.
The same thing that we did with shapeType, we can do with color.
(The first time I tried to write this, I named the global variable `color` instead of `shapeColor`. Then my code didn't work, because the line `shapeColor = color(…)` tried to use the value of my `color` variable as a function, instead of seeing the p5.js color function.)
Here's something fun you can do with hues. "Walk" the color around the color wheel, by changing its hue slightly .
You may have noticed that we had to renumber the array indices in, for example, `let x = shape[2]` each time we added things to the shape. Also, the fact that the x position is `shape[2]` instead of `shape[3]` makes the code difficult to read, and fragile.
We can fix this by representing a shape as an Object instead of an Array.
This sketch has the same behavior as the previously step; it is simply more readable.
This concludes this tutorial. The following tutorial demonstrates how to make this program more concise (without changing its behavior), by using some additional JavaScript features.
function setup() {
createCanvas(windowWidth, windowHeight);
}
function draw() {
}
function mouseDragged() {
ellipse(mouseX, mouseY, 20, 20);
return false;
}