How to Transform SVG Elements
So far, we mainly used absolute positions to define elements on the SVG canvas. This can sometimes be tricky. Let’s look at the head of this lamp in this example. We need to know where the end of the arm is to position it correctly, and the whole head is tilted. And what if we need to make a slight adjustment? Like changing the rotation of one of the arms.
We can also define each part in its own space so that they are relative to an anchor point. Then, move and rotate them to their correct place. In this example, we build this lamp in a way that allows us to easily adjust the position of the arm and the head of the lamp.
You can morph the two lamps above to each other by dragging their head. You can adjust their height by dragging the head vertically and tilt the head by dragging it horizontally. We will cover how to make this lamp interactive in the Interaction chapter.
How to Rotate and Translate SVG ElementsThe base of the lamp
Lets start with the easy part. We create the lamp’s base with two ellipses.
The arm of the lamp
Now, let’s start building up the arm of the lamp. We draw it in its own space independent of its actual position and direction. We go from the 0,0
coordinate and draw a straight line upwards with the path
element. And add a circle for the joint.
For now, most of this is invisible. The 0,0
coordinate is at the top left corner of the canvas, and the arm is pointing upwards. We move it to the correct position in the next step.
We can move the arm into position by grouping the elements together and using the transform
property. We use the translate
function to move the origin to the 70, 170
position.
Transformations are relative to the origin of the element. Initially this was the origin of the viewBox, the top-left corner. By applying the translate
function we also moved the origin to the 70, 170
position. As a result, we can rotate the arm around the joint with the rotate
function.
Now let’s add the second piece of the arm. We can do this by nesting another g
element inside the previous ones. We move this group to the end of the first arm by applying another translate
transformation (we move it vertically by -70, that matches the length of the first arm).
Building up the arm this way has two benefits. First, we can define the line with the same attributes as the previous one. The arm doesn’t need to know where its absolute position is on the canvas. We simply define a line that goes from the 0,0
position straight up to 0,-70
.
The second benefit of defining the arms this way is that we can rotate the second arm piece around the joint by applying a rotate
transformation. Now lets turn back this second arm to balance out the lamp. We wrap the second arm piece into another group and apply another rotate
transformation.
Now lets add the third piece that connects the arm to the head of the lamp. We can do this by nesting another g
element inside the previous ones. We move this group to the end of the second arm by applying another translate
transformation (we move it vertically by -70, that matches the length of the second arm).
Finally, let’s add a placeholder for the lamp’s head. For now let’s just add a placeholder that we are going to replace in the next step.
The head of the lamp
To simplify things, lets start sketching the head of the lamp as a separate SVG. We will put everything together in the next step. The origin here represents the anchor point that will be connected to the arm.
First we add a gold circle slightly below the anchor point. This will be our light bulb.
Note that these images appear bigger than in the final result because the
width
and height
do not match the size defined by the
viewBox
.
Then, we create the back side of the lamp’s shade from two quadratic Bézier curves. This one comes before the circle because it is behind the light bulb. Hover over the coordinates in the code or on the image to see how they are positioned.
Then we create the front part of the lamp’s shade from two other quadratic Bézier curves. This shape has almost the same values as the back side, except the bottom curve is bending upwards.
Finally, we add a rounded rectangle to finish the head of the lamp.
Putting it all together
Now let’s put together, the base, the arm and the head of the lamp.
In the Interaction example we are going to add interactivity to this lamp. We are going to add event handlers to adjust the height and the tilt of the head of the lamp.