Introduction to (Web) Programming

Lab 9: 2D arrays and the HTML canvas

shortcut to main problems


General instructions

Console exercises

> let pair = [9, 22];
> pair[0]
> pair[1]
> pair[0] = pair[0] * 2;
> pair

> let aa = [[250, 170, 200, 210],
            [191, 101, 111, 121],
            [202, 222, 212, 112],
            [233, 113, 103, 103],
            [244, 254, 224, 234]];
> aa.length
> aa[2]
> aa[3].length
> aa[4][0]
> aa[0][3]

Consider this little HTML canvas:

> let cvs = domGetElement('canvas');
> cvs.width
> cvs.height
> domSetStyle(cvs, 'backgroundColor', 'rgb(0, 200, 0)');

> let ctx = cvs.getContext('2d');
> ctx.fillStyle = 'red';
> ctx.fillRect(50, 20, 30, 10);

> ctx.clearRect(0, 0, cvs.width, cvs.height);

> ctx.beginPath();
> ctx.lineWidth = 4;
> ctx.strokeStyle = 'blue';
> ctx.moveTo(0, 0);
> ctx.lineTo(90, 10);
> ctx.lineTo(20, 30);
> ctx.stroke();

> ctx.beginPath();
> ctx.fillStyle = 'yellow';
> ctx.arc(200, 40, 8, 0, Math.PI);
> ctx.fill();

Main exercises

For the rest of the lab, you need to download and unzip this archive. It consists of several files. You will work in lab9.js, but will also want to look over (and possibly make a few changes to) lab9.html and lab9.css. You should test your work by loading (and reloading when necessary) lab9.html in your browser. (You may still find it helpful to tests parts of your work in the console.) You are encouraged to try my solution to see the tasks assigned below in action.

  1. Read over the code in lab9.js to see what global variables (and constants) have already been defined and to see what functions have been provided for you. (Many will serve as templates for how to solve the remaining exercises.)

  2. Modify the initialize function so that when the page is loaded, the background of the canvas is set to a color of your choice. Modify the values of the constants ROWS, COLUMNS, BLOCK_HEIGHT, and BLOCK_WIDTH so that blocks are neither too small nor too large and that the overall canvas height is roughly 600 pixels wide by 400 pixels high. Test the appearance of an individual block in the top-left and bottom-right corners of your canvas like this:

     > drawBlock(0, 0, 'red');
     > drawBlock(COLUMNS-1, ROWS-1, 'yellow');

    Drawing a face

  3. Complete drawSquare(x, y, length, color) so that it draws a filled square of the specified color and side length (in pixels) that is centered around canvas coordinates (x, y). That means its top-left coordinate should be half of length smaller than the given center point. Use .fillStyle and .fillRect. Test by clicking the sketch button which should draw a blue square in the center of the canvas.

  4. Complete drawCircle(x, y, radius, color) so that it draws a filled circle of the specified color and radius centered at canvas coordinates (x, y). Test by clicking the sketch button which should now also draw a purple circle to the left and above the blue square.

  5. Add code to sketch() so that when the sketch button is clicked, it draws a smiling face, using another circle and a few lines, something like:

    Making it rain

  6. Complete resetDrops() so that the global variable gDrops is an array of length dropCount where each element is a pair - itself an array of length 2 of - of integers, corresponding to a random x-y point on the canvas. Use gCanvas.height, Math.random(), etc. Test by clicking on the blue rain button - it should paint a small blue circle for each point on the gDrops array.

  7. Modify blueRain() so that each time the corresponding button is clicked, the drops appear slightly lower (i.e., with a greater y coordinate) on the canvas. Make sure the function clears the canvas before repainting it. Repeatedly clicking the rain button should give the appearance of the blue circles falling toward the bottom of the canvas. You can reload the page to reset the array of random drops.

    256 shades of green

  8. Complete drawGreenRow() so that it creates an array of random numbers ranging from 0 to 256 (by calling makeRandomArray) that of length COLUMNS and then paints the array as a chain of blocks in the middle row of the canvas where the color of each block should be a shade of green based on the value of the number in the array. Test by clicking (repeatedly) on the green row button.

  9. Complete makeRandom2dArray(rows, columns) so that it returns a two-dimensional array: an array that is of length rows such that each of its elements is an array of length columns and where each of those elements is a random number ranging from 0 to 256). Use .push and call makeRandomArray. You can test your function with supplied aaToString which returns a string representation of a two-dimnesional array of numbers. Each character should be D (for “Dark”) or l (for “light”) depending whether the number is less than or greater than or equal to 128. For example:

     > let rr = makeRandom2dArray(3, 7);
     > console.log(aaToString(rr));
  10. Complete drawGreenGrid() so that it paints the canvas full of greenscaled blocks according to the values in the underlying global array gBlocks (which, at this point, should be created correctly by the existing code). Test by clicking (repeatedly) on the green grid button.

  11. Complete bubbleArray(a) so that, assuming a is an array of numbers, it considers, from the start to the end of the array, each pair of concecutive numbers in the array and if the value at the lower index is greater than the value at the next index, then the two values are exchanged in the array. This concept is called “bubbling” - as in the larger values will bubble toward the end of the array. This can be visualized on a small array like so:

     44   77   22   99   33   15
     44   77   22   99   33   15
     44   22   77   99   33   15
     44   22   77   99   33   15
     44   22   77   99   33   15
     44   22   77   33   99   15
     44   22   77   33   15   99

    You can test your code by clicking (repeatedly) on the bubble right button. You should see each row of the green grid change where the brighter greens appear, more and more, at the right side of each row.

  12. Complete rotateDown so that for each “column” in the global array gBlocks, elements are one position down and the bottom-most element replaced what was the top-most element. Test by clicking (repeatedly) on the rotate down button.