In this lab we will explore transformations in HTML Canvas. For this lab, use the Share button at the top right to create a multiplayer reply that everyone in your group can edit. (One person should create the repl and invite all the others.) As you go through the lab, the text poses a number of questions. Discuss these with your group and make sure that everybody understands and agrees with the answer.
Study the code
Fork a copy of the lab starter code. This lab is divided into several parts. When you run the program at first, you will see links to each of the parts. These are stored in separate files listed in the file tab at left. You should begin with part one.
Part One: Translations
Look at the code in the file named part1.html. You will see that the draw() method creates four squares of different colors. Currently they are all drawn on top of one another so that only the green one is visible in the result. (To see the outcome of this code, run the repl and click the link for Part One.)
We want to add translations between each of the drawn squares so that they do not appear directly on top of one another. For example, if you insert the following just before the green square is drawn, it will shift its location.
graphics.translate(30,30);
Experiment with adding different translations before each square is drawn. How do translations added in one location affect the rest of the squares? If you put two translations in one place, what is the effect? Can you use negative numbers as translations? (Be careful; if you move too far in any direction your square might be outside the visible area and seem to disappear!)
To complete this section, try to adjust your added translations so as to produce the image below (the blue square should be in the top left of the window):
Part Two: Rotations with Translations
Next move on to part2.html. Again you have four colored squares and need to insert transformations in between. This time the necessary transformations will be a combination of translation and rotation. To warm up, try the following before the green square is drawn:
graphics.rotate(Math.PI/4); graphics.translate(56,28);
Is the result what you expected? Now try reversing the order of the translation and the rotation. Is the result different? Again, is it what you expected? Experiment with other combinations, taking care to keep the squares within the visible region of the window.
To complete this section, try to add translations and rotations between the drawn squares so as to produce the image below (again, the blue square should be in the top left of the window). Note that you may order the transformations in whatever manner seems easiest to you.
Part Three: Translation, Rotation, and Scaling
Now it is time to add scaling to the mix. This part is located in the file part3.html. Again you have four colored squares and need to insert transformations in between. This time the necessary transformations will be a combination of scaling, translation and rotation. To warm up, try the following before the green square is drawn:
graphics.scale(0.5,0.5); graphics.translate(80,80);
Is the result what you expected? Note that the distance moved by the translation is affected by the scaling that happened just before. Now try reversing the order of the translation and the scale. Is the result different? Again, is it what you expected? Experiment with other combinations, scaling both larger and smaller.
To complete this section, try to add transformations between the drawn squares so as to produce the image below. Note that you may order the transformations in whatever manner seems easiest to you. In my solution, I sometimes perform the translation before the scaling, and other times after, so as to avoid computing distances on a diagonal. The scale factor between squares of different sizes here is 0.7
Part Four: Animated Square
This section is contained in the file part4.html. We are going to introduce a simple animation through use of Javascript's interval timer. This is a feature of the language that allows a piece of code to be executed repeatedly at some fixed interval.
When you first look at the file, it just draws a stationary square in the upper left corner, and a larger circle in the middle of the page. Eventually we'll animate the square to move around the circle. The first thing to do is to get it moving.
Right now, the square is only being drawn once. We need to change that and make it draw repeatedly. To do so, replace the single call to drawSquare (line 25) with a new command that sets an interval timer to repeatedly call our function. The line below will activate our function every 150 milliseconds.
timer = setInterval(drawSquare, 150)
The result will still look unchanged. We're drawing the square multiple times a second, but each square is drawn on top of the last so we see no difference. We need to add a transformation between successive drawings in order to make each one different. Add the line below inside drawSquare:
graphics.rotate(angle);
You should see your first sign of movement. As the rotation transforms accumulate, new squares are drawn at ever-increasing rotation angles. Each rotation is composed with the one before.
Currently, the square is being drawn at (0,0) -- right next to the axis of rotation. Modify the call to graphics.fillrect so that the square is drawn at (100,0) instead. What happens to the animation? Can you explain why?
Your final task is to modify the program again so that the motion of the square follows the circle drawn in the center of the window. You should be able to do this with a single strategically-placed transformation. Can you figure out where to put it?
Finish Up
You do not have to turn this lab in, but make sure that everyone in your group understands the code by the end of the lab. Feel free to experiment with different transformations and variations on the interval timer. We will continue working with the ideas from this lab in Homework 3.