If you're seeing this message, it means we're having trouble loading external resources on our website.

If you're behind a web filter, please make sure that the domains *.kastatic.org and *.kasandbox.org are unblocked.

## Computer programming - JavaScript and the web

### Course: Computer programming - JavaScript and the web>Unit 4

Lesson 6: Transformations

# Multiple transformations

Now that you've seen the basics of translation, rotation, and scaling, let's talk about using all of them together, and some of the complexities we brushed over at the beginning.

### Order matters

When you do multiple transformations, the order makes a difference. A rotation followed by a translate followed by a scale will not give the same results as a translate followed by a rotate by a scale. Here is an example program that demonstrates that:
Which order you use depends on what your desired effect is. Just keep in mind that you're moving the graph paper, not the object itself, and you should find an order that works for you.

### The transformation matrix

Every time you do a rotation, translation, or scaling, the information required to do the transformation is accumulated into a table of numbers. This table, or matrix has only a few rows and columns, yet, through the miracle of mathematics, it contains all the information needed to do any series of transformations. And that’s why the `pushMatrix()` and `popMatrix()` have that word in their name.
What about the push and pop part of the names? These come from a computer concept known as a stack, which works like a spring-loaded tray dispenser in a cafeteria. When someone returns a tray to the stack, its weight pushes the platform down. When someone needs a tray, he takes it from the top of the stack, and the remaining trays pop up a little bit.
In a similar manner, `pushMatrix()` puts the current status of the coordinate system at the top of a memory area, and `popMatrix()` pulls that status back out. The preceding example used `pushMatrix()` and `popMatrix()` to make sure that the coordinate system was "clean" before each part of the drawing. In all of the other examples, the calls to those two functions weren’t really necessary because there were no subsequent transformations, but it doesn’t hurt anything to save and restore the grid status. As a best practice, always use those functions when you're doing any transformations.
There is also a `resetMatrix()` function that resets the matrix back to its very original state (the "identity matrix"), but the push and pop functions are nearly always the better approach.
Want to learn or review how matrices work in Algebra? You can go through Matrices on Khan Academy, in particular, the Geometric transforms with matrices section.

## Want to join the conversation?

• in the next challenge i am stuck on the last step it says my translations is incorrect but thats not true heres my code please answer

angleMode = "degrees";
var backgroundColor = color(135, 206, 250);
var sunColor = color(255, 255, 0);
var sunStrokeColor = color(200, 200, 0);
var sunDiameter = 100;

var drawCloud = function() {
noStroke();
fill(255, 255, 255);
ellipse(0, 0, 126, 97);
ellipse(60, 0, 70, 60);
ellipse(-60, 0, 70, 60);
};

var drawSunRay = function() {
fill(sunColor);
noStroke();
triangle(0, 90, -40, 0, 40, 0);
};

var drawSun = function() {
//draw sun rays
for(var i = 0; i < 342; i+=30) {
pushMatrix();
translate(200,200);
rotate(i);
drawSunRay();
popMatrix();
}
//draw center of sun
fill(sunColor);
stroke(sunStrokeColor);
ellipse(width/2, height/2, sunDiameter, sunDiameter);
};

//draw background
background(backgroundColor);

//draw sun
var scaleF = 2;
pushMatrix();
translate(5-5*41,5-40*5);
scale(scaleF);
drawSun();
popMatrix();
//draw clouds
pushMatrix();
translate(300,268);
drawCloud();
popMatrix();
• You always want the sun to be in the center (200, 200) regardless of scaleF
Try
translate(200 - 200 * scaleF , 200 - 200 * scaleF);
because when the sun is scaled, the new center is 200*scaleF. To get it back to (200, 200), you have to translate it back scaleF*200-200. because translating towards the origin is negative, it should be 200 - 200*scaleF
• Do the width and height variables change if I change the scale?
• In the challenge: optical illusion, why do we have to translate and do all that stuff when we can simply draw the circles at 200, 200?
• Because that is the purpose of the challenge: To practice transformation functions.
• Will a colorMode function call between pushMatrix and popMatrix affect the color mode of the stuff after popMatrix?
• Yes , it will.
`colorMode` wrapped with `pushStyle` and `popStyle` will not.
• On Challenge: Shining Scaling Sun I need help! I did steps 1 & 2 myself but I am stuck on step three. I used the help code. I have the following code:
``var scaleF = function() { //scale factor    pushMatrix();    translate(___-_____*___,_____-___*_____);    scale(scaleF);    drawSun();    popMatrix();};``

and i can't seem to find the values to use in the `translate();` function. The page is also saying that my sun is either too big or too small and thet i should set the existing variable scaleF to a value between 1 and 3 but I cannot seem to find it.
• translate(200-200*scaleF,200-200*scaleF);
• plz correct me if I am wrong: resetMatrix() would take us to the very start of the code and push/pop would take us to the last time they were used for a transformation, hence better practice to use these,right?
• Correct. `resetMatrix` is rarely the correct call. It is another transformation function, and not a restoration matrix function.
• It says: The preceding example used pushMatrix() and popMatrix() to make sure that the coordinate system was "clean" before each part of the drawing.

But really, doesn't popMatrix() restore the "clean" version after our drawing is done, not before?
• It's talking about the next iteration of drawing, by saving the matrix and then restoring it, the next time the drawing is performed the matrix is unchanged from what it was before the first drawing. It could probably be reworded (to make sure it was 'clean' you'd technically use resetMatrix() as mentioned, otherwise you are expecting it to be 'clean' and simply not 'dirtying' it (by pushing and popping it); the distinction matters more if you are using other people's code (because if you call someone else's code, they may not have used pushMatrix() and popMatrix() to prevent changing the matrix).
• Does the Khan Academy library have a "reflect" function ?
• You can set `scale` to a negative value. Look:
``var img = getImage("avatars/avatar-team");imageMode(CENTER);image(img, 100, 200, img.width / 2, img.height / 2);pushMatrix();translate(300, 200); // we translate the image to our ideal spotscale(-1, 1); // we set the x-scale to -1 and the y-scale to 1, flipping the imageimage(img, 0, 0, img.width / 2, img.height / 2); // we display the imagepopMatrix();// dashed linefor(var i = 0; i < height; i += 10) {    line(width / 2, i, width / 2, i + 2);}``

To see a live example, go here: https://www.khanacademy.org/computer-programming/flipped-images-example/4571085845889024