# context.translate()

## Overview

The `context.translate()` method moves the origin of the context's coordinate system by passing it two values:

``context.translate(x, y);``

The `x` value moves the origin of the coordinate system horizontally and the `y` value moves it vertically. For example, `context.translate(90, 60)` moves the origin 90 pixels to the right and 60 pixels down.

## Translate the Origin to Move the Drawing Paper

While transforming the context's coordinate system may sound highly mathematical, it actually simplifies any math we might need to do when drawing.

Think of moving the origin of the coordinate system like moving a sheet of drawing paper. If we were drawing a house on a sheet of paper, we would move the paper so the house's position is directly under our pencil, and then we would draw the house. Once the house is directly under our pencil, we can draw the house without thinking about its position.

On the canvas, the origin of the coordinate system (0, 0) is the point directly under our pencil. In this example, we draw a house at the origin and use the `context.translate()` method to position it wherever we want.

We start by translating the origin to (0, 0). This doesn't move the origin at all, for now, which is what we want. We'll move the origin later.

``context.translate(0, 0); // Position house here``

Then, we draw our house at the origin.

``````context.fillStyle = '#FFFF00';
context.fillRect(0, 0, 120, 100); // Yellow house
context.fillStyle = '#99CCFF';
context.fillRect(15, 20, 20, 40); // Left window
context.fillRect(85, 20, 20, 40); // Right window
context.fillStyle = '#FF0000';
context.fillRect(45, 40, 30, 60); // Red door``````

Finally, we have defined a function that will draw a set of axes at the origin of the coordinate system. This will help us see the position of the origin any time we want. Call it after drawing the house.

``drawAxes();``

At this point, we have drawn a yellow house with two windows and a red door at the origin of the coordinate system, which is in the top left corner of the canvas.

Go back up to the top of the program where we translate the origin of the coordinate system to (0, 0). Change the line of code to move the origin to (100, 50). Then, try drawing the house at different positions.

``context.translate(100, 50);  // Position house here``

To learn more about the coordinate system, setting fill colors, and drawing rectangles, visit the and fillRect() lessons.

Quick Reference:

Message Log

## Challenge 1

Right now, this program draws a French flag at the position (0, 0).

Use the `context.translate()` method to draw the French flag at the position (120, 40).

Message Log

## Combine Multiple Translations

When we use the `context.translate()` method to position a drawing, it is important to remember that we are moving the entire coordinate system and not just a single drawing.

In this example, we translate the origin of the coordinate system to position (100, 50) and draw a house and a set of axes.

``````context.translate(50, 100); // Position of the first house
context.fillStyle = '#FFFF00';
context.fillRect(0, 0, 120, 100); // Yellow house
context.fillStyle = '#99CCFF';
context.fillRect(15, 20, 20, 40); // Left window
context.fillRect(85, 20, 20, 40); // Right window
context.fillStyle = '#FF0000';
context.fillRect(45, 40, 30, 60); // Red door
drawAxes();``````

Then, we translate the origin of the coordinate system to position (200, 0) and draw second house and a second set of axes.

``````context.translate(200, 0); // Position of the second house
context.fillStyle = '#FFFF00';
context.fillRect(0, 0, 120, 100); // Yellow house
context.fillStyle = '#99CCFF';
context.fillRect(15, 20, 20, 40); // Left window
context.fillRect(85, 20, 20, 40); // Right window
context.fillStyle = '#FF0000';
context.fillRect(45, 40, 30, 60); // Red door
drawAxes();``````

The second house is not drawn at (200, 0) in absolute coordinates on the canvas. It is drawn at (250, 100) because, when we apply the second translation, we are doing it in a coordinate system that has already been moved. The second house is drawn 200 pixels to the right of the origin for the first house. And if we did another translation and drew a third house, it would be positioned relative to the origin for the second house.

Quick Reference:

Message Log

## Challenge 2

Right now, this program draws a French flag at the position (0, 0).

Copy the code to draw two more French flags. Use the `context.translate()` method to position the first French flag at (20, 40). Then, position the second French flag 200 pixels to the right of the origin for the first French flag, and position the third French flag 140 pixels down and 80 pixels to the left of the origin for the second French flag.

Message Log

## Restore the Coordinate System After a Translation

Sometimes we want to combine our translations, like when we are drawing a row of houses. But usually, we want to restore the coordinate system immediately after drawing a house so we can position and draw something else. Because the transformation matrix for the coordinate system is stored in the canvas's drawing state, we can use the `context.save()` and `context.restore()` methods to save the coordinate system and restore it back to its original state.

In this example, we start by saving the drawing state when the origin of the coordinate system is in the top left corner of the canvas:

``context.save(); // Save original drawing state``

Then, we translate the origin of the coordinate system to (200, 50) and draw a house:

``````context.translate(200, 50); // Position of the first house
context.fillStyle = '#FFFF00';
context.fillRect(0, 0, 120, 100); // Yellow house
context.fillStyle = '#99CCFF';
context.fillRect(15, 20, 20, 40); // Left window
context.fillRect(85, 20, 20, 40); // Right window
context.fillStyle = '#FF0000';
context.fillRect(45, 40, 30, 60); // Red door``````

Before translating the origin again and drawing a second house, we restore the drawing state we saved earlier:

``context.restore(); // Restore original drawing state``

This returns the origin back to the top left corner of the canvas. So, when we translate the origin to (50, 150) and draw a second house, the second house is positioned at (50, 150) in absolute coordinates on the canvas.

``````context.translate(50, 150); // Position of the second house
context.fillStyle = '#FFFF00';
context.fillRect(0, 0, 120, 100); // Yellow house
context.fillStyle = '#99CCFF';
context.fillRect(15, 20, 20, 40); // Left window
context.fillRect(85, 20, 20, 40); // Right window
context.fillStyle = '#FF0000';
context.fillRect(45, 40, 30, 60); // Red door``````

Quick Reference:

Message Log

## Challenge 3

Use the `context.save()`, `context.restore()`, and `context.translate()` methods to draw the first French flag at position (10, 50). Then, restore the coordinate system to its original state and draw the second French flag at position (220, 100);

Message Log

## Use a Function to Translate a Drawing

It doesn't make sense to keep copying the same code over and over again every time we want to draw a yellow house or French flag. To re-use a drawing, we should draw it in a function.

In this example, we define a `drawYellowHouse()` function to draw a yellow house.

``````function drawYellowHouse(x, y) {
context.save();
context.translate(x, y);
context.fillStyle = '#FFFF00';
context.fillRect(0, 0, 120, 100); // Yellow house
context.fillStyle = '#99CCFF';
context.fillRect(15, 20, 20, 40); // Left window
context.fillRect(85, 20, 20, 40); // Right window
context.fillStyle = '#FF0000';
context.fillRect(45, 40, 30, 60); // Red door
context.restore();
}``````

The `drawYellowHouse()` function has two parameters: `x` is the x-coordinate of the house's origin and `y` is the y-coordinate. We save and restore the drawing state by calling the `context.save()` method at the start of the function and the `context.restore()` method at the end. This restores both the coordinate system and the `context.fillStyle` property to the way they were before the function made any changes.

Now we can draw as many yellow houses as we want simply by calling the `drawYellowHouse()` function and passing it the coordinates for the house.

``````drawYellowHouse(40, 40);
drawYellowHouse(120, 200);
drawYellowHouse(280, 100);``````

To learn more about functions and saving and restoring the drawing state, visit the Functions and save() / restore() lessons.

Quick Reference:

Message Log

## Challenge 4

The `drawPineTree()` function draws a pine tree at the origin. Re-define the function so it draws the pine tree at coordinates passed into the function.

Then, use the function to draw pine trees at the positions (5, 40), (105, 10), (205, 60), and (305, 30).

Message Log

## Nested Frames of Reference

When we are in a city and someone asks us for directions to another part of the city, we usually don't direct them using latitude and longitude as though they were coming from a different part of the globe, never mind coordinates to find the Earth in the solar system in the Milky Way Galaxy in the universe. Same thing when we are in a mall or even in a single room.

It is usually much more convenient and less confusing to direct someone using a local frame of reference rather than an absolute frame of reference.

In this example, we add details to the windows and the red door in the yellow house, and we make drawing those details simpler by translating to a local frame of reference.

We start by defining a `drawWindow()` function. In the yellow house, the first window is a rectangle positioned at (15, 20) in the local coordinates of the house with a width of 20 and a height of 40. As long as a window was just a rectangle, it made sense to use the `context.fillRect()` method to position the window. But now that a window is going to be a little drawing on its own, with lots of rectangles inside of it, we are going to turn it into a function and position it using the `context.translate()` method.

``````function drawWindow(x, y) {
context.save();
context.translate(x, y);
context.fillStyle = 'White';
context.fillRect(0, 0, 20, 40); // White border
context.fillStyle = '#99CCFF';
context.fillRect(2, 2, 7, 7); // Pane of glass
context.fillRect(11, 2, 7, 7);
context.fillRect(2, 11, 7, 7);
context.fillRect(11, 11, 7, 7);
context.fillRect(2, 20, 16, 18);
context.restore();
}``````

Note that the white rectangle we draw to create a white border for the window is positioned at (0, 0) and the first pane of glass is positioned at (2, 2). Those coordinates are in the local frame of reference of the window. We don't care where the window is positioned in the house or where the house is positioned on the canvas.

Next, we define a `drawRedDoor()` function and draw the red door using local coordinates also:

``````function drawRedDoor(x, y) {
context.save();
context.translate(x, y);
context.fillStyle = '#FF0000';
context.fillRect(0, 0, 30, 60); // Red door
context.fillStyle = '#99CCFF';
context.fillRect(6, 6, 18, 12); // Pane of glass
context.fillStyle = '#FFD700';
context.fillRect(22, 28, 5, 5); // Door knob
context.fillRect(10, 45, 10, 5); // Mail slot
context.restore();
}``````

Again, note that the window in the door is positioned at (6, 6) in the local coordinates of the door. If we were going to give the window a stained glass design instead of making it a simple rectangle, we would draw the stained glass design by translating into the local coordinates of the door's window. It makes our drawing simpler and less confusing.

Now that we are using functions to draw our windows and red door, we update the `drawYellowHouse()` function:

``````function drawYellowHouse(x, y) {
context.save();
context.translate(x, y);
context.fillStyle = '#FFFF00';
context.fillRect(0, 0, 120, 100);
drawWindow(15, 20);
drawWindow(85, 20);
drawRedDoor(45, 40);
context.restore();
}``````

Finally, we draw two yellow houses, one at (100, 50) and the other at (200, 50).

``````drawYellowHouse(50, 100);
drawYellowHouse(200, 100);``````

Change the coordinates of one of the yellow houses to see the entire house move relative to the canvas. Change the coordinates of one of the windows inside the `drawYellowHouse()` function to see an entire window move relative to the yellow house. Drawing nested objects in local coordinates is much easier than drawing them in absolute coordinates.

Quick Reference:

Message Log

## Challenge 5

Define the `drawOrnament()` function with three parameters so it positions the ornament at (`x`, `y`) and fills it with the color `color`.

``````function drawOrnament(x, y, color) {
context.save();
context.translate(x, y);
context.fillStyle = color;

// DRAW ORNAMENT IN LOCAL COORDINATES HERE

context.restore();
}``````

The ornament is drawn by drawing three rectangles on top of one another so the centers of the three rectangles are lined up. Use the dimensions in the diagram below to draw the three rectangles.

Then, copy the `drawPineTree()` function you defined in Challenge 4 and draw some ornaments on the tree inside the function definition using local coordinates for the tree. Choose your own ornament positions and colors to create an aesthetic drawing. Your drawing will look similar to, but not exactly like the image above. Call the `drawPineTree()` function in your program to draw the tree at (100, 40):

``drawPineTree(100, 40);``

When you re-position the tree, the ornaments should move along with the tree. If your program seems to be working, mark the challenge as complete by selecting "Yes, it looks good".

If you need help drawing the ornament, visit the and fillRect() lessons.

Quick Reference:

Message Log

## Anchor Points

Right now, we are positioning the yellow house by its top left corner. That's the origin we are using for the house's local coordinate system.

When drawing a house, it makes sense to use its top left corner as the origin for the local coordinate system. But when positioning a house on the canvas, it makes more sense to position the house according to where it is sitting on the ground, not hanging in the air.

In this example, we re-define the `drawYellowHouse()` function so we are passing it the coordinates for its bottom center point, not its top left point.

We start by changing its parameters from `x` and `y` to `centerX` and `groundY`. Then, we save the drawing state as usual and translate the origin of the coordinate system to (`centerX`, `groundY`), which is the anchor point for the house.

``````function drawYellowHouse(centerX, groundY) {
context.save();
context.translate(centerX, groundY); // The house's anchor point

// Code to draw the house

context.restore();
}``````

Now, we could use the anchor point as the origin of the local coordinate system to draw the house, but that would be a pain. It is easier to draw the house when the origin is at the top left corner of the house, not at the bottom center point. So, we are going to use the `context.translate()` method again to move the origin before drawing. This gives us the best of both worlds: a good anchor point for positioning the house on the canvas and a good origin point for drawing the house itself.

``````function drawYellowHouse(centerX, groundY) {
context.save();
context.translate(centerX, groundY); // The house's anchor point
context.translate(-60, -100); // The origin for drawing the house

// Code to draw the house

context.restore();
}``````

Since we know the house is 120 pixels wide and 100 pixels tall, we can move the origin from the bottom center point to the top left corner by moving it left 60 pixels (half the width) and up 100 pixels. Now that the origin of the coordinate system back in the top left corner, we can draw the house just like we did before.

``````function drawYellowHouse(centerX, groundY) {
context.save();
context.translate(centerX, groundY); // The house's anchor point
context.translate(-60, -100); // The origin for drawing the house
context.fillStyle = '#FFFF00';
context.fillRect(0, 0, 120, 100);
drawWindow(15, 20);
drawWindow(85, 20);
drawRedDoor(45, 40);
context.restore();
}``````

Change the value assigned to the variable `groundY` at the top of the program to change the y-coordinate of the ground. We have also made minor changes to the `drawYellowHouse()` function so you can see the anchor point of the house and the origin point for drawing the house. To show the origin point of the house, uncomment out the first call to `drawAxes()` inside the `drawYellowHouse()` function.

Quick Reference:

Message Log

## Challenge 6

Copy the `drawPineTree()` function you defined in Challenge 4 (the one without the ornaments), and re-define it so you can position a tree on the canvas using the bottom center point of the tree as its anchor point.

Hint: A pine tree is 100 pixels wide and 240 pixels tall.

Then, draw a pine tree positioned on the ground at (150, `groundY`), where `groundY` is the local variable storing the y-coordinate of the ground.

``````drawPineTree(150, groundY);
``````
Message Log

## Use Translation with Other Transformations

While good anchor points are helpful in positioning drawings on the canvas, they are necessary when scaling or rotating drawings.

In this example, we draw two houses. The anchor point of the green house is its top left corner. The anchor point of the yellow house is its bottom center point. We can scale both houses by setting a scale factor.

Right now, both houses are sitting on the ground with a scale factor of 1. Assign the local variable `scaleFactor` at the top of the program a value of 1.2 to see what happens.

``var scaleFactor = 1.2;``

While both houses scale, only the yellow house remains anchored on the ground. Note that the anchor point does not move when a house is scaled.