Categories SVG

No Time To Die – Part 2

Post date October 6, 2020

It’s time for part 2 – grouping and transforming SVG paths.

A short reminder: in first part I have showed you how to create simple SVG shapes if you have a raster image. We went through some of the path syntax mysteries and ended up with all the simple shapes ready to merge into letters.

What we do today is creating this image as SVG:

No time to die movie title

To do this we will use SVG transforms and put use element into use.

SVG Transforms

All of the transforms will go into transform property like this:

<path transform="translate(180 0)"></path>

We will use following transforms:

  • translate – to move elements to left, right, top and bottom
  • scale – to change size or mirror the element
  • rotate – to rotate the element around a point

SVG use

In the process we will reuse both single shapes and groups of shapes multiple times and it’s good to know how SVG’s use element works.

Let’s have a look at the example:

<svg width="120" height="100" viewbox="0 0 120 100">
    <defs>
        <path id="m-one" d="M0,0m0,92h25l2,-6,-13,-51z"></path>
        <path id="m-two" d="M0,0m40,92h30l-24,-92h-20l-5,17z"></path>
    </defs>
    <g id="M">
        <use href="#m-one"/>
        <use href="#m-two"/>
        <use href="#m-two" transform="translate(40)"/>
    </g>
</svg>

First, we declare <defs> in the beginning of the SVG file. Then we give every reusable element an id. Outside the <defs> we will instruct the browser to render these shapes by using href attribute with an id as value.

Reused shapes can be modified with inline attributes like transform, fill, stroke, which is great. It makes resulting code shorter (path’s d attribute can get veery long) and it gives the possibility to use the same elements in multiple icons – you create one arrow, and reuse it as left arrow, right arrow and so on, changing only its transform.

<use> is a self-closing tag, which means we cannot put anything inside it. That space is reserved for shadow DOM containing copies of referenced elements.

Compositing SVG group from paths

Some of the letters can be assembled easily just by grouping shapes we created earlier. For example letter “E”:

<svg width="120" height="100" viewbox="0 0 120 100">
    <defs>
        <path id="i" d="M0,0h32v92h-32z"></path>
        <path id="e-one" d="M0,0m35,0h30v33z"></path>
        <path id="e-two" d="M0,0m54,26v36l-19,-18z"></path>
        <path id="e-three" d="M0,0m35,92h31v-40z"></path>
    </defs>
    <g id="E" >
        <use href="#i"/>
        <use href="#e-one"/>
        <use href="#e-two"/>
        <use href="#e-three"/>
    </g>
</svg>

We can go one step further and put this group in defs to reuse later as <use href="#e"/>.

<svg width="120" height="100" viewbox="0 0 120 100">
    <defs>
        <path id="i" d="M0,0h32v92h-32z"></path>
        <path id="e-one" d="M0,0m35,0h30v33z"></path>
        <path id="e-two" d="M0,0m54,26v36l-19,-18z"></path>
        <path id="e-three" d="M0,0m35,92h31v-40z"></path>
    
        <g id="e">
            <use href="#i"/>
            <use href="#e-one"/>
            <use href="#e-two"/>
            <use href="#e-three"/>
        </g>
    </defs>
    <use href="#e"/>
</svg>

Letter "E" in SVG
Note, that whatever we have put in defs, will not be rendered. Only the resulting letter “E” will appear on the screen. If you try to inspect it with developer tools, you would see something like this:

DOM structure of SVG for letter "E"

Translation in SVG

To translate an element by 30 units to the right and 20 units to the bottom use transform="translate(30 20)". Note, that these are SVG internal units and not pixels.

If you only want to move an element horizontally, you can omit the second value: transform="translate(30)".

To create the letter “M”, we would write:

<svg width="120" height="100" viewbox="0 0 120 100">
    <defs>
        <path id="m-one" d="M0,0m0,92h25l2,-6,-13,-51z"></path>
        <path id="m-two" d="M0,0m40,92h30l-24,-92h-20l-5,17z"></path>
    </defs>
    <g id="M">
        <use href="#m-one"/>
        <use href="#m-two"/>
        <use href="#m-two" transform="translate(40)"/>
    </g>
</svg>

Elements m-one and first m-two would we rendered as defined in their d attributes. The second m-two would be moved 40 units to the right.

Letter M created with SVG

Rotating in SVG

To rotate an element by 30 degrees use transform="rotate(30)".

Rotation will happen around the point at 0,0, which is rarely what we need. We can add the coordinates of the point, we want our element to rotate around like this: transform="rotate(30, 10, 15)". It translates into: rotate by 30 degrees around the point with coordinates 10 (x-axis) and 15 (y-axis).

We will use rotation and translation to built the letter “O”:

<svg width="120" height="100" viewbox="0 0 120 100">
    <defs>
        <path id="o-one" d="M0,0m36,92c-36,0,-36,-92,0,-92z"></path> 
    </defs>
    <g id="O">
        <use href="#o-one"/>
        <use href="#o-one" transform="rotate(180) translate(-82 -92)"/>
    </g>
</svg>

Transforms always happen in order they are written in. In our case it means: first rotate, than translate.

SVG transforms to rotate and move element

Scaling SVG

To scale an element – make it 2 times wider and 5 times taller – use transform="scale(2,5)".

Elements are scaled so that the top left corner (point (0,0)) does not move.

We will use transform="scale(-1,1)" to mirror a part of the letter “T” (invert it horizontally and keep original vertically):

<svg width="120" height="100" viewbox="0 0 120 100">
    <defs>
        <path id="t-one" d="M0,0m0,41v-41h19z"></path>
        <path id="i" d="M0,0h32v92h-32z"></path> 
    </defs> 
    <g id="T"> 
         <use href="#t-one"/> 
         <use href="#i" transform="translate(21)"/> 
         <use href="#t-one" transform="translate(73) scale(-1 1)"/> 
    </g> 
</svg>

SVG transforms to scale nad translate an element

Assembling the full image

Now, as we have assembled all the letters from basic shapes, we can use them to put together the static image from the beginning of this post:

SVG with text "No Time To Die"

Our SVG code looks like this:

<svg width="1000" height="1000" viewbox="0 0 1000 1000">
    <defs>
        <path id="n-one" d="M0,0m0,26v66h26v-11z"></path>
        <path id="n-two" d="M0,0m0,6v-6h36l41,86v6h-36z"></path>
        <path id="o-one" d="M0,0m36,92c-36,0,-36,-92,0,-92z"></path>
        <path id="t-one" d="M0,0m0,41v-41h19z"></path>
        <path id="I" d="M0,0h32v92h-32z"></path>
        <path id="m-one" d="M0,0m0,92h25l2,-6,-13,-51z"></path>
        <path id="m-two" d="M0,0m40,92h30l-24,-92h-20l-5,17z"></path>
        <path id="e-one" d="M0,0m35,0h30v33z"></path>
        <path id="e-two" d="M0,0m54,26v36l-19,-18z"></path>
        <path id="e-three" d="M0,0m35,92h31v-40z"></path>
        <g id="N">
            <use href="#n-one"/>
            <use href="#n-two"/>
            <use href="#n-one" transform="rotate(180) translate(-77 -92)"/>
        </g>
        <g id="O">
            <use href="#o-one"/>
            <use href="#o-one" transform="rotate(180) translate(-82 -92)"/>
        </g>
        <g id="T">
            <use href="#t-one"/>
            <use href="#I" transform="translate(21)"/>
            <use href="#t-one" transform=" translate(73) scale(-1 1)"/>
        </g>
        <g id="M">
            <use href="#m-one"/>
            <use href="#m-two"/>
            <use href="#m-two" transform="translate(40)"/>
        </g>
        <g id="E">
            <use href="#I"/>
            <use href="#e-one"/>
            <use href="#e-two"/>
            <use href="#e-three"/>
        </g>
        <g id="D">
            <use href="#I"/>
            <use href="#o-one" transform="rotate(180) translate(-77 -92)"/>
        </g>
    </defs>

    <use href="#N" transform="translate(8 11)"/>
    <use href="#O" transform="translate(96 11)"/>
    <use href="#T" transform="translate(8 113)"/>
    <use href="#I" transform="translate(96 113)"/>
    <use href="#M" transform="translate(136 113)"/>
    <use href="#E" transform="translate(250 113)"/>
    <use href="#T" transform="translate(96 225)"/>
    <use href="#O" transform="translate(180 225)"/>
    <use href="#D" transform="translate(180 327)"/>
    <use href="#I" transform="translate(260 327)"/>
    <use href="#E" transform="translate(300 327)"/>
</svg>

If you are asking yourself where do the numbers in letters’ translate come from – I have read them from the jpeg file the same way I have read the coordinates to create shapes in the firs part of this series.

That’s it for this part. See you in the next part – animation.

Leave a Reply

Your email address will not be published. Required fields are marked *