© Alex Libby  2018
Alex LibbyBeginning SVGhttps://doi.org/10.1007/978-1-4842-3760-1_2

2. Adding SVG Content to a Page

Alex Libby1 
(1)
Rugby, Warwickshire, UK
 

Life is full of shapes. Square, round, oblong – it doesn’t matter what: it’s still a shape.

I don’t know if there was someone famous who came up with that erudite comment, but it can equally apply to SVG images – even though we can create some intricate designs, at their core each will be made up of individual shapes.

These shapes might be any one of eight different types: we can create squares, rectangles, circles, ellipses, lines, polylines, polygons and paths, which when put together will form our final design. If we cast our minds back to the exercise we worked through in Chapter 1, “Introducing SVG”, we created a simple circle with a silver color used to fill the center:
<svg>
  <circle cx="60" cy="60" r="50" stroke="black" stroke-width="5" fill="silver"/>
</svg>

This simple one-liner (for the purposes of this code I’m excluding the <svg> tags, which have to be present anyway), is all that is required to create a circle. Question is – is it that easy to create the other basic shapes?

Well, thankfully it is – with the exception of the multipoint shapes (polygons, polylines, and paths), it’s a cinch to create these basic shapes, so let’s dive in and take a look at the code to produce each one in turn.

Implementing SVG Shapes

When working with SVG images, there are a number of basic shapes available for us to use – the purpose of many of these will be obvious from their names, although some less so! In all cases they are designed to help make it easier to read our code and ultimately keep the SVG documents as short as possible (avoiding duplication where practical).

Any shape we implement will be as an element – we touched on the different options for adding these to a page back in Chapter 1. Each has its own merits; for convenience we will add ours using the inline method, so that we can then manipulate them using standard CSS styling methods.

Do not feel constrained to use just one method when adding SVG images – most of the ones we touched on in Chapter 1 can be used, but some (such as iframe or embed) should be avoided if possible!

Enough talking – let’s make a start and explore the shapes we can use, starting with the humble square and rectangle.

Creating Squares and Rectangles

The first of the basic shapes we will take a look at is the humble square (and it’s cousin, the rectangle) – as someone once said, everything is made up of building blocks, so it seems only sensible to start with these two shapes!

The code to create both shapes is very straightforward, so without further ado, let’s get cracking on our first exercise of this chapter:

CREATING SQUARES AND RECTANGLES

  1. 1.
    Let’s begin by adding the following code to a new document, saving it as squares.html at the root of our project folder:
    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="utf-8">
      <title>Beginning SVG: Creating a simple example</title>
      <link rel="stylesheet" href="css/squares.css">
    </head>
    <body>
    </body>
    </html>
     
  2. 2.
    Next, we’re going to provide a little styling – in a new file, add the following code , saving it as squares.css in the css subfolder of our project area:
    @font-face {
      font-family: 'pt_sansregular';
      src: url('../font/pt_sansregular.woff') format('woff');
      font-weight: normal;
      font-style: normal;
    }
    body { font-family: 'pt_sansregular', sans-serif; padding: 2rem; }
    span { width: 200px; vertical-align: top; }
    svg { display: inline-block; height: 200px; padding-top: 20px; }
    #squareID, #rectangleID { margin-left: -125px; }
     
  3. 3.
    In between the <body> tags, go ahead and add the following code:
      <h2>Beginning SVG: Drawing Squares and Rectangles</h2>
      <link rel="stylesheet" href="css/squares.css">
      <span>Adding a square:</span>
      <svg id="squareID">
        <rect x="10" y="10" width="100" height="100" stroke="darkgrey" fill="transparent" stroke-width="5"/>
      </svg>
      <span>Adding a rectangle</span>
      <svg id="rectangleID">
        <rect x="10" y="10" width="150" height="100" stroke="grey" fill="transparent" stroke-width="5"/>
      </svg>
     
  4. 4.

    Save this file, then go ahead and view the results in a browser  – if all is well, we should see something akin to the screenshot shown in Figure 2-1.

     
../images/461821_1_En_2_Chapter/461821_1_En_2_Fig1_HTML.jpg
Figure 2-1

Drawing squares and rectangles

See how easy that was? Creating simple SVG images is very straightforward – after all, our code uses standard HTML formatting, so there is no need to learn a specialist syntax when creating our images. The code, however, does introduce us to some unfamiliar keywords, so let’s pause for a moment and take a look at these in more detail.

Understanding How the Code Works

At this point, some of you may be wondering why, if we look at the code closely, we appear to have two <rect> elements in use, when we clearly can see a square and rectangle on screen!

The truth is that although both clearly look different, they use the same element; this means they can share the same properties. If, for example, we were creating a square, then the values for width and height would be identical, as shown in our example – these would be different if we wanted to create a rectangle:
<svg id="squareID">
  <rect x="10" y="10" width="100" height="100" stroke="darkgrey" fill="transparent" stroke-width="5"/>
</svg>

We start with the standard <svg> tags to define our element – you will see these in use whenever you create an SVG image. Next, we have our <rect> element, which has a number of defined attributes that govern its size, position (x and y), fill color, and thickness (or stroke-width) of the border.

The key to this shape (and any other) is in the positioning – each shape is positioned using a defined grid position (as we touched on back in Chapter 1), where the top left corner of our viewport is point 0, 0. In our example, our boxes (although it isn’t displayed as such in print), are displayed 10 pixels to the right and 10 pixels down, from point zero.

We will touch on stroke, stroke-width, and fill in more detail later in this chapter in the section “Painting elements.”

We then simply pass suitable values for both width and height – the radius values are omitted, as we don’t want curved corners on our shapes . These attributes are listed in full in Table 2-1.
Table 2-1

Attribute Properties for Rectangles

Attribute

Purpose

x

The x position of the top left corner of the rectangle.

y

The y position of the top left corner of the rectangle.

width

The width of the rectangle.

height

The height of the rectangle.

rx

The x radius of the corners of the rectangle.

ry

The y radius of the corners of the rectangle.

The remaining basic shapes are as straightforward to create, so let’s continue with this theme, and take a look at how we can create SVG circles and ellipses.

Drawing Circles and Ellipses

The second basic shape we will now look at is the circle (and its cousin, the ellipse) – this kind of reminds me of the phrase “to be thrown a curveball.” I don’t know why, only except to say that there are no hazards to watch for when creating these shapes!

The code to create both shapes is very straightforward, so without further ado, let’s get cracking on the next exercise of this chapter:

CREATING CIRCLES AND ELLIPSES

Much of the code that we need to use is already in place, so to make it easier, we can simply take a copy of the previous CSS and HTML files, then adjust as necessary:
  1. 1.
    We’ll begin by taking a copy of squares.html, then renaming it as circles.html – go ahead and replace the code between the <body> tags with this:
    <h2>Beginning SVG: Drawing Circles and Ellipses</h2>
    <span>Adding a circle:</span>
    <svg id="circleID">
      <circle cx="60" cy="65" r="55" stroke="black" fill="transparent" stroke-width="5"/>
    </svg>
    <span>Adding an ellipse:</span>
    <svg id="ellipseID">
      <ellipse cx="75" cy="75" rx="70" ry="50" stroke="#a6a6a6" fill="transparent" stroke-width="5"/>
    </svg>
     
  2. 2.
    Go ahead and change the CSS style sheet link from squares.css to circles.css:
    <link rel="stylesheet" href="css/circles.css">
     
  3. 3.
    Next, take a copy of the squares.css file, then rename it as circles.css – remove the last rule, and replace it with this:
    #circleID, #ellipseID { margin-left: -125px; }
     
  4. 4.

    Save the contents of both files, then go ahead and fire up circles.html in a browser: if all is well, we should see two circular shapes, as indicated in Figure 2-2.

     
../images/461821_1_En_2_Chapter/461821_1_En_2_Fig2_HTML.jpg
Figure 2-2

Drawing circles and ellipses

See how easy it is to create basic circular elements using SVG? There is very little different when compared to creating a square or rectangle – we use the same format of code , although some of the attributes will be different. Let’s pause for a moment to review how our code works, and these attributes, in more detail.

Exploring How the Code Works

If we take a close look at the code we’ve just created, we can start to see some similarities – both to what we’ve just created in the previous exercise, and between how the circle and ellipse are created.

For example, we can use the same stroke, fill and stroke-width attributes as before – these have not changed. What is of more interest to us though are the attributes for sizing each element – both use the same cx and cy values to define the starting position of the circle. Unlike the circle where the radius is evenly defined (using the r value), an ellipse is clearly wider than it is taller – for this, we need to use the rx and ry values to define its size, as outlined in Table 2-2.
Table 2-2

Attribute Properties for Circles and Ellipses

Attribute

Purpose

r

The radius of the circle.

cx

The x position of the center of the circle.

cy

The y position of the center of the circle.

rx

The x radius of the ellipse.

ry

The y radius of the ellipse.

To put this in context of our example, our circle starts at point 60, 65 and has a radius value of 55. The ellipse is a little wider, so we must allow for this in our example – it starts at position 75,75: it has a x radius value of 70 and y radius value of 50. Note though that these values are from the center of the shape outwards; multiply both values by 2, to get the true size of the ellipse.

Okay – let’s change tack: not every shape we need to create will be a simple square or circle ; what about creating multisided shapes, for example? Thankfully it’s just as easy to create these shapes, so let’s dive in and take a look.

Drawing Lines, Polylines, and Polygons

At its heart, every SVG shape we create is made up of individual lines – I need hardly say that each goes from point A to B!

Okay – I confess: I am stating the obvious but with good reason. This next bunch of shapes relies on using this principle to work, so understanding which pair of values relates to which point in a shape is key to manipulating how they appear on the page. To see what I mean, let’s dive in and create our next three shapes – a line, polyline, and polygon – as part of our next exercise.

DRAWING LINES, POLYLINES, AND POLYGONS

As in previous exercises, much of the code that we need to use is already in place, so to make it easier, we can simply take a copy of the previous CSS and HTML files, then adjust as necessary:
  1. 1.
    We’ll begin by taking a copy of squares.html, then renaming it as lines.html – go ahead and replace the code between the <body> tags with this:
    <h2>Beginning SVG: Drawing Lines, Polylines and Polygons</h2>
    <span>Adding a line:</span>
    <svg id="lineID">
      <line x1 = "20" y1 = "20" x2 = "175" y2 = "180" stroke = "black" stroke-width = "3"/>
    </svg>
    <span>Adding an polyline:</span>
    <svg id="polylineID">
      <polyline points = "20,20 40,25 60,40 80,120 120,140 200,180" fill = "none" stroke = "black" stroke-width = "3"/>
    </svg>
    <span>Adding an polygon:</span>
    <svg id="polygonID">
       <polygon points = "60,10 140,10 190,70 190,130 140,190 70,190 10,130 10,70" fill = "gainsboro" stroke = "black" stroke-width = "3"/>
    </svg>
     
  2. 2.
    Next, go ahead and replace the link to lines.css at line 6, with this:
    <link rel="stylesheet" href="css/lines.css">
     
  3. 3.
    Now take a copy of the lines.css file, then rename it as circles.css – remove the last rule, and replace it with this:
    #lineID, #polylineID, #polygonID {
      margin-left: -116px;
    }
     
  4. 4.

    Save the contents of both files, then go ahead and fire up lines.html in a browser : if all is well, we should see three line shapes, as indicated in Figure 2-3.

     
../images/461821_1_En_2_Chapter/461821_1_En_2_Fig3_HTML.jpg
Figure 2-3

Drawing lines, polylines, and polygons

By now, some of the terms we’ve used should start to be a little more familiar – such as stroke, fill, and stroke-width. We will cover these shortly, but for now it’s more important to understand how we’ve constructed our shapes, so let’s dive in and take a look at our code in more detail.

Exploring How the Code Works

Creating polyline (or for that matter, polygon) shapes can be something of a paradox – the code may look more complicated, but in reality it is simpler, as we have fewer attributes that need to be configured. Those that do need to be configured are listed in Table 2-3.
Table 2-3

Attributes for Lines, Polylines, and Polygons

Attribute

Purpose

x1, y1

The x and y positions of point 1 (our starting point).

x2, y2

The x and y positions of point 2 (our finishing point).

points

A list of points, each separated by a comma, space, EOL, or line feed character. Each must contain an x and y coordinate – the drawing automatically closes the path, so a final line will be drawn from the last set of points to the starting set.

Note: this applies to lines and polygons only; to see how it works for polylines, add a fill color to the shape.

If we take a look at our code examples, we can see the first two sets of attributes in use within the line example – these simply use the SVG grid position system to locate the starting and finishing points within our view port: x1 = "20" y1 = "20" x2 = "175" y2 = "180".

A little further down, the points attribute comes into play – again, we specify our coordinates using the x, y format . So for example, the starting point for our octagon is 60, 10, or 60 units in from top left, and 10 down. We then continue all the way round the shape, providing suitable coordinates to complete our shape.

Okay – let’s change tack: we have one final set of shapes to explore; these open up a wealth of possibilities, although they will take a little more work to come to grips with how they can be configured! I’m talking about paths and markers, so let’s dive in and explore the potential uses of these two elements in more detail.

Constructing Paths and Markers

So far, we’ve dealt with relatively simple shapes , which all follow a defined design – we can clearly recognize a circle as such, or a single line connecting two points! (Yes, it might sound like I’m really stating the obvious again, but yes, there is a point – stay with me on this…)

All of those shapes have one thing in common – they are made up of lines that connect two points; multiple lines together will create a shape. However, what if we wanted to create an abstract shape, which is not a recognizable design, such as a square?

Enter the world of SVG paths – we can provide a series of coordinates that when joined, form our final design. The beauty though is that we can apply all manner of different styles to it, just as we would do for a standard circle or square. We can really go to town on our design – to get a taster, try opening the gradients.html file that is in the gradients folder within the code download that accompanies this book….

I’ll bet good money that your initial response will be something along the lines of Yikes! What the…? Does this sound about right? Don’t worry – this wasn’t meant to shock you, but to give you a flavor of what is possible when we work with SVG paths. Let’s take it back a few notches and check out a simple example of what we can achieve, as shown in Figure 2-4.
../images/461821_1_En_2_Chapter/461821_1_En_2_Fig4_HTML.jpg
Figure 2-4

A simple example of an SVG path

This curve example was taken from a useful Codepen of examples (available at https://codepen.io/chriscoyier/pen/NRwANp ), created by the CSS expert Chris Coyier of CSS-Tricks.​com fame; below is the code extract used to create our example:
  <svg viewBox="0 0 10 10" class="svg-4">
    <path d="M2,5 C2,8 8,8 8,5"/>
  </svg>

Clearly something a little easier to understand! The question is, what does it all mean? This is a really useful concept to learn when working with SVGs, so let’s break it down into its constituent parts.

Understanding Our Code in Detail

The first line of code is the standard opening tag for any SVG shape or design; we’ve met this already in previous exercises, so should be a little more familiar by now. The real magic happens in line 2 – we have the (aptly named!) <path> tag, inside which we assign a series of numbers and or letters to create our design.

There is, however, method in the apparent madness of that string of characters – they are a series of commands to define how our shape should appear. To make sense of it, there is one important concept we should be aware of: the difference between absolute and relative commands .

What do I mean by this? Well – let’s take the first command: M2,5. Put very simply, it means “move to the exact location 2, 5”. The next command, C2,8 8,8 8,5, is a little more complex: we use this to create a Bezier curve. The starting point for it was defined with the initial command; the next three coordinates define the degree of curve and end point of our Bezier curve. Keeping this in mind, let’s assign those coordinates to an edited version of the previous screenshot (Figure 2-5).
../images/461821_1_En_2_Chapter/461821_1_En_2_Fig5_HTML.jpg
Figure 2-5

An edited version of our Bezier curve SVG

Note that in the above screenshot, I’ve only included the coordinates of the C command, to show how it matches with our original command.

We’ve touched on the need to understand the difference between absolute and relative commands – the key to making paths work is this: most commands come in pairs – either as uppercase characters, or as lowercase equivalents. The uppercase characters represent absolute commands, whereas the lower case ones are relative. To put this into context, our example directed the starting point to be at the absolute location of 2,5. If we had made it relative (i.e., used a lowercase m instead), then it would read as “move 2 to the right, and 5 down,” from our current location instead.

Working with paths can open a real minefield of possibilities – the d attribute we met at the beginning of this section has a mini-syntax in its own right! It’s absolutely worth exploring what is possible; some people may say it’s simpler just working with paths (as you can do just about everything we’ve already covered), but the key to remember is that using predefined shapes will make it easier to read the code in your final solution.

For a good in-depth tutorial, check out Chris Coyier’s guide on using paths, which is available at https://css-tricks.com/svg-path-syntax-illustrated-guide/ . This contains a list of the different commands we can use to create individual paths, in addition to a good explanation of how paths operate.

Let’s move on – we can do a huge amount with the powerful path element, but to really take things up a level, how about adding markers to our design ? Mark…huh? I hear you ask – what would that give us…?

Adding Markers to SVG Paths

Aha – let me explain: who hasn’t used Google Maps in some form or other? You enter the zip code or name of a location, and up pops a little pointer to indicate the location, right?

That’s a marker – trust me, it’s nothing more complicated than simply identifying a point on our design! We use the same principle when working with SVG designs. There’s a variety of different uses for markers – we could use them as indicators on maps, or for a wiring schematic we might create, where clarity is paramount, irrespective of the size of the design.

Let’s put this to the test, and construct a simple SVG of a line that has a marker element at one end – this will be the subject of our next exercise.

DRAWING PATHS AND MARKERS

We’re going to break with tradition, and create this as a Codepen (for variety), so go ahead and browse to https://codepen.io , then follow these steps:
  1. 1.
    We’ll start by adding this block of code into the HTML section of our pen – this creates our basic line and marker:
    <h2>Beginning SVG: Drawing Paths and Markers</h2>
    <svg>
      <defs>
        <marker id="circle1" markerWidth="8" markerHeight="8"
                refX="5" refY="5" orient="auto">
          <circle cx="5" cy="5" r="3" fill="black"/>
          <circle cx="5" cy="5" r="2" fill="lightgray"/>
          <path d="M 4,3.5 L 6.5,5 L 4,6.5 Z" fill="slategray"/>
        </marker>
      </defs>
      <line x1="50" y1="120" x2="250" y2="50" stroke="black" stroke-width="5" marker-end="url(#circle1)" />
    </svg>
     
  2. 2.
    In the CSS section, drop in these styles – they are not obligatory but will add a little variety to the title styling. You can leave these styles out if you prefer – the demo will work just fine without them:
    @import url('https://fonts.googleapis.com/css?family=PT+Sans');
    body {
      font-family: 'PT Sans', sans-serif;
      padding: 2rem;
    }
     
  3. 3.

    Go ahead and save the pen by clicking on the Save button – if all is well, we should see something akin to the screenshot shown in Figure 2-6.

     
../images/461821_1_En_2_Chapter/461821_1_En_2_Fig6_HTML.jpg
Figure 2-6

Drawing paths and markers

You can see a working version in a Codepen at https://codepen.io/alexlibby/pen/goXbRJ , or peruse a version available within the code download that accompanies this book (look for the paths.html file).

Our design is deliberately meant to look simple, but if you take a look at the code in more detail, you can see a few keywords we’ve not touched on to date. Let’s dive in and take a look at them in more detail.

Understanding How Our Code Works

If we concentrate on the core part of our code, we can see this block – it kicks off with a <defs> element, which allows us to create an element for later reuse:
<defs>
  <marker id="circle1" markerWidth="8" markerHeight="8"
              refX="5" refY="5" orient="auto">
    <circle cx="5" cy="5" r="3" fill="black"/>
    <circle cx="5" cy="5" r="2" fill="lightgray"/>
    <path d="M 4,3.5 L 6.5,5 L 4,6.5 Z" fill="slategray"/>
  </marker>
</defs>

The <defs> element is not rendered immediately, but instead defines an object for later reuse – it’s best to think of any object stored within a <defs> block as a template or macro created for future use.

Within our <defs> element, we create a <marker> tag, to which we apply an ID of circle1; the viewport size of our marker is defined by the markerWidth and markerHeight values, and will be attached using the refX and refY coordinates.

Inside our marker element, we define two circles – one is filled in with the color black, with the second placed inside it and colored light gray. (The final design looks like one circle with a thick border, but it is two circles that overlay each other). We then add a slate gray-colored arrowhead, which is applied using the path command; this is then completed with the closing </marker> and </defs> tags. Our marker is then applied to the line element we’ve drawn – we attach the marker at the end point of our line, using the marker-end attribute, as indicated in this code extract:
<line x1="50" y1="120" x2="250" y2="50" stroke="black" stroke-width="5" marker-end="url(#circle1)" />

The value passed via marker-end references the object we created in our <defs> block, which we discussed earlier in this section.

We could have used marker-start to attach our marker at the start point of our line, but I don’t think the final result would look quite as good! We’ve touched on some of the attributes that can be used – Mozilla has a useful article outlining each option in more detail, which is available at https://developer.mozilla.org/en-US/docs/Web/SVG/Element/marker .

Let’s change tack and focus on something a little more complex – we’ve touched on using paths as a way of creating more abstract shapes, but there will be occasions where we need something a little more…practical! Thankfully we can use paths to achieve this; let’s work on a more practical example of using this element in more detail.

Creating More Advanced Shapes

Up to this point, our examples have been relatively straightforward – it’s time we took things up a level again and produced something a little more complex, to show what can be achieved with SVG.

A good example is the classic gauge – we can use this to measure and / or change any setting, such as opacity or measure broadband speed. Okay, perhaps a little contrived, yes, but the point being that if we need to measure a range of values, or quickly change them, then a gauge might be a useful tool to use.

The great thing about SVG is that we can easily create a basic gauge – it will automatically resize, without loss of function, and can later be animated if desired. Over the course of the next exercise, we’re going to explore how to create such a gauge, using an example adapted from a Codepen created by Adao Junior.

CONSTRUCTING A CIRCULAR GAUGE

Let’s make a start:
  1. 1.
    In a new file , go ahead and add the following code, saving it as advanced.html in our project area:
    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="utf-8">
      <title>Beginning SVG: Creating a more advanced example</title>
      <link rel="stylesheet" href="css/advanced.css">
    </head>
    <body>
      <h2>Beginning SVG: Creating a Circular Gauge</h2>
    </body>
    </html>
     
  2. 2.
    Go ahead and add the following code in between the <body> tags – this creates the gauge and accompanying text:
    <svg id="gauge" x="0px" y="0px" width="176px" height="168px" viewBox="0 0 76 68">
    <g>
      <text transform="matrix(1 0 0 1 22.9209 43.4141)" fill="#708090">45%</text>
    </g>
    <path fill="none" stroke="#222729" stroke-width="2" stroke-miterlimit="10" d="M16.652,65.29
      C8.984,58.838,4.112,49.171,4.112,38.366c0-19.424,15.746-35.171,35.17-35.171c19.424,0,35.17,15.747,35.17,35.171c0,10.805-4.872,20.473-12.54,26.924"/>
    <path class="completion" fill="none" stroke="#708090" stroke-width="5" stroke-miterlimit="10" d="M17.107,65.29
      C9.44,58.838,4.567,49.171,4.567,38.366C4.567,20.6,17.74,5.911,34.852,3.532"/>
    <text id="complete" transform="matrix(1 0 0 1 21.3916 51.7891)" fill="#000000">completion</text>
    </svg>
     
  3. 3.
    We need to add a little styling to finish off the effect – go ahead and add the following to a new file, saving it as advanced.css within the css subfolder that is in our project area:
    @font-face { font-family: 'pt_sansregular'; src: url('../font/pt_sansregular.woff') format('woff'); font-weight: normal; font-style: normal; }
    body { font-family: 'pt_sansregular', sans-serif; padding: 2rem;
      font-size: 18px; }
    #complete { font-size: 8px; }
     
  4. 4.

    Save both files – if we preview the results in a browser, we should see something akin to the screenshot shown in Figure 2-7.

     
../images/461821_1_En_2_Chapter/461821_1_En_2_Fig7_HTML.jpg
Figure 2-7

Creating a circular gauge

You can see the original version of this demo in a Codepen at https://​codepen.​io/​junior/​pen/​RWQver.

Although the code looks complex, we’ve touched on most of the key terms used within – in fact, the only terms we’ve yet to meet are <text> and <transform>! There are some useful concepts within this code we should be aware of, so let’s pause for a moment to explore how the gauge was created in more detail.

Dissecting Our Gauge Code

For this demo, you might well be forgiven if an initial look at this code prompts a…shall we say…colorful response! It looks scary, but in reality it is easier to understand than it might first appear:

We begin with defining our SVG viewport, and set a viewport of around 50% its size – this will have the effect of zooming in the image when displayed. Inside our SVG, the first element we create is a <text> element, which displays the percentage completed in the gauge (in this case 45%).

The first of the two <path> elements creates the dark-colored back line, over which we show the 45% completed <path>, which is styled using a slate gray color. In both cases, we’re setting stroke widths, which define the thickness of each <path> element, and which is drawn centered on the path. We then close out the SVG with a second <text> element, which contains the word complete, and uses a transform attribute to help center it in both the SVG and against the percentage value.

Note

To really understand the detail of how each path works, try breaking the d= attribute into separate lines, where you see an uppercase or lowercase letter. I would recommend taking a look at the excellent article by Chris Coyier at https://css-tricks.com/svg-path-syntax-illustrated-guide/ ; this shows you how to translate these letters (from any SVG), into something you can recognize as an action, such as M to move to an absolute point.

Let’s move on – it’s time to spice things up a little and go really abstract! Over the course of the next chapter, we will dive into how we can manipulate images and text when working with SVG . However, we can equally use them as a basis for creating abstract shapes using clip-paths; this tool is something of a special case, as it can be used both in a standard and SVG capacity. To see what we mean, let’s dive in and see how crazy things might get…

Creating Unusual Shapes with Clip-Paths

Clip-paths  – this is where we can really have some fun! This feature originated as part of the initial SVG spec from 2000, but has since been moved into the CSS Masking module, so it can be used in either a SVG or CSS capacity.

Put simply, we use clip-paths to specify a clipping path that can be applied to any element – this includes both text and images. This clip-path can take any shape we desire and can be created using the shape functions we’ve covered thus far in this chapter. Anything outside of the clip-path won’t be displayed – in effect, a clip-path is a form of mask, which we can use to block out undesired content, without physically removing it from the original image.

The best way to understand how this work is to see it in action, so without further ado, let’s put together a simple demo to show off the effects of applying a clip-path to an image. Our demo will use an image of houses in a sunset – you can see the original image on the publicdomainvect​ors.​org site at https://publicdomainvectors.org/en/free-clipart/Houses-on-the-horizon-vector/1525.html .

CREATING AN UNUSUAL SHAPE

Let’s make a start:
  1. 1.
    We’ll start with add the following code to a new file, saving it as clippath.html in our project area:
    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="utf-8">
      <title>Beginning SVG: Creating a simple example</title>
      <link rel="stylesheet" href="css/clippath.css">
    </head>
    <body>
      <h2>Beginning SVG: Drawing unusual shapes with clip-path</h2>
      <svg height="0" width="0">
        <defs>
          <clipPath id="svgPath">
            <path fill="#FFFFFF" stroke="#000000" stroke-width="1.5794" stroke-miterlimit="10" d="M215,100.3c97.8-32.6,90.5-71.9,336-77.6
          c92.4-2.1,98.1,81.6,121.8,116.4c101.7,149.9,53.5,155.9,14.7,178c-96.4,54.9,5.4,269-257,115.1c-57-33.5-203,46.3-263.7,20.1
          c-33.5-14.5-132.5-45.5-95-111.1C125.9,246.6,98.6,139.1,215,100.3z"/>
          </clipPath>
        </defs>
      </svg>
      <img src="img/houses.svg">
    </body>
    </html>
     
  2. 2.

    Next, go ahead and take copies of the css and img folders from clippath folder within the code download that accompanies this book. Store these in the project area – they contain some simple styling required for the demo, along with our source SVG file.

     
  3. 3.

    We’re almost there – save the file, then go ahead and preview the results in a browser; if all is well we should see the weird image shown in Figure 2-8.

     
../images/461821_1_En_2_Chapter/461821_1_En_2_Fig8_HTML.jpg
Figure 2-8

Our crazy clip-path image...

Okay – yes, perhaps describing this image as weird is a little over the top! However it does show that we can create some odd-shaped images using the clip-path property within SVG . The great thing about it is that we’re simply using path values in a similar manner to that in the previous exercise – each is a set of commands that, when executed, draws our random shape as a series of connected points.

We open with our now familiar opening <svg> tags, inside which we’ve set up a <defs> element – this is to define our clip-path as a shape that can be reused. The shape itself starts at the absolute point of 215,100 and then simply moves around in a series of relative moves to various points in our viewport. The clip-path is then completed with the closing tags, ready for use in our page.

At the bottom of our HTML code, we’ve put a simple link into a SVG image – we tie this all together with the img { clip-path: url(#svgPath); } statement in our CSS file, which applies our SVG clip-path to our image.

We’ll revisit working with images and SVG in the next chapter, “Working with Images and Text.” To understand more of what is possible, please refer to the great article by Sarah Soueidan, available at http://www.sarasoueidan.com/blog/css-svg-clipping/ .

Phew – we’ve come to the end of our journey through each of the different types of shapes available when working with the SVG format; it’s up to us to choose the right ones to create our next killer design. A part of this though is adding color – we’ve touched on this at various points with attributes such as fill or fill-opacity in previous exercises, so let’s take a moment to review this in a little more detail.

Painting Elements

Any SVG we create will look very dull if we simply created a line drawing – sometimes this may be necessary (in the case of an electronics schematic), but more often than not, we will need to add color. Question is – how?

Well, we’ve already done so in the examples we’ve created so far, but without realizing it! If you take a look at the examples we’ve worked through to date, you can’t help but see code such as this example:
<path fill="#FFFFFF" stroke="#000000" stroke-width="1.5794" stroke-miterlimit="10"...
These terms are just four of the options available for providing color – we start with the basics such as fill for painting shapes, through to stroke for defining the outline color of that shape, or stroke-linecap for determining how the ends of our segment lines will appear. There is a host of options we can use, so to bring all of the possibilities together from the various demos thus far, I’ve summarized the details in Table 2-4.
Table 2-4

A summary of Painting Options for SVGs

Attribute

Purpose

fill

Fills in the color of any SVG shape – can take any CSS color value, such as HEX, named colors, or RGB/a values.

fill-opacity

Used to set the opacity of the color specified in fill.

fill-rule

Determines how which side of a path is in a shape, and how the fill property paints that shape.

stroke

Defines the outline color of an element – accepted values can be none (default), or <paint>, context-fill, or context-stroke.

stroke-width

Controls the width of a border on SVG shapes.

stroke-linecap

Sets the starting and ending points of a border on SVG shapes – can take butt, square, or round as values.

stroke-linejoin

Controls how the joint between two segments is drawn – can accept the values miter, round, or bevel.

stroke-miterlimit

If two segments with miter joints meet at a sharp angle, this setting imposes a ratio of the miter length to the stroke-width. Exceeding this limit will change a miter joint to a bevel.

stroke-dasharray + stroke-dashoffset

Determines when and where to draw a dash array (a series of dashes instead of a continuous line).

stroke-opacity

Determines the opacity level of the outside border.

Some settings can be set using plain CSS, and not SVG-specific commands – it’s best to test each in turn to find out what you can use.

These are just some of the options open to us when painting SVG elements – there is no secret recipe to creating a really stunning piece; that old adage of “practice makes perfect” comes into its own in this respect. The best way to learn is to choose an SVG and then open it up in a text editor and just change the values.

Granted we can learn what each does, but sometimes there really is no better way than to just go for it! And that just happens to be a perfect lead-in for our next exercise – let’s put this into practice by adjusting colors in both radial and linear patterns.

Creating Gradients and Patterns

Up until this point, we’ve talked about painting (or filling) SVG elements with a chosen shade of color – there is one thing though: it doesn’t matter what color we choose, it will always be just one color for that part of our design.

After a while this is likely to become a little dull – it might work if most of your projects focused solely on using single, bold colors, but this clearly won’t suit everyone! What if we could include a graduated color into our designs though…?

Well, we can – in the same way as we might using standard CSS, we can apply gradient effects to SVG elements. Gradient effects come in two different types – linear (centered along one line), or radial (radiates out from a central point). A gradient is best explained with an example, so without further ado, let’s crack on with our next exercise.

Constructing Gradients

When creating gradients, we can really have some fun and apply all manner of different effects – sometimes though just keeping it to a select few can create more of an impact! However many colors we decide to use, the fun is in trying out different combinations, and that taking a work-in-progress approach to this may pay dividends in the longer term (what you find now may be more useful later, and so on…).

For our next exercise, we’re going to run with this work-in-progress approach and use it as a basis for starting to add gradients to an SVG image. I would absolutely encourage you to try different colors when creating gradients – the next exercise is all about illustrating the process of adding color gradients, rather than the final selected colors! We’ll make use of an SVG image from the freesvgimages.​com website; this is a good site to bookmark as a useful source of images for your projects.

CREATING A GRADIENT

Let’s make a start:
  1. 1.
    We’ll begin as always with a new document – go ahead and add the following code , saving it as gradients.html in our project area:
    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="utf-8">
      <title>Beginning SVG: Creating a simple example</title>
      <link rel="stylesheet" href="css/gradients.css">
    </head>
    <body>
      <h2>Beginning SVG: Adding linear gradients to SVG images</h2>
    </body>
    </html>
     
  2. 2.

    We are going to add a little extra styling for the title on our page – for this, extract a copy of gradients.css and drop it into the css subfolder of our project area. It will make use of the fonts folder we already have from previous exercises, and which should already be in this folder.

     
  3. 3.

    Next, go ahead and open up a copy of the wip.svg file from the code download that accompanies this book – copy the entire contents (yes, all 248 lines of it) and paste immediately before the closing </body> tag in our code.

     
  4. 4.
    We are now at the point where we need to add our gradient effect – for this, go ahead and insert a couple of blank lines after the opening <svg> tag, then add the following code as highlighted:
    <svg id="message" x="0px" y="0px" width="612px" height="792px" viewBox="100 150 612 792" enable-background="new 0 0 1212 1392">
      <defs>
        <linearGradient id="wip-gradient" x1="0%" y1="0%" x2="100%" y2="0%">
        <stop offset="0%" style="stop-color:#FF9133;" />
        <stop offset="100%" style="stop-color:#FF0015;" />
        </linearGradient>
      </defs>
     
  5. 5.
    We have our gradient definition now in place, but for it to be applied, we need to make one final change to our SVG element. For this, look for this code, on or around line 19:
    <path fill-rule="evenodd"...
    Go ahead and insert this attribute after the opening <path element, as highlighted:
    <path fill="url(#wip-gradient)" fill-rule="evenodd"...
     
  6. 6.

    Save the file, then preview the results in a browser – if all is well, we should see something akin to the screenshot shown in Figure 2-9, which I hope might make you smile at the irony of it:

     
../images/461821_1_En_2_Chapter/461821_1_En_2_Fig9_HTML.jpg
Figure 2-9

A radial gradient applied to our SVG

Hopefully you had a little chuckle at the irony of the image – you can see the original on the freesvgimages.​com site at https://www.freesvgimages.com/im-a-work-in-progress/ . Ultimately though the point being that as in life, nothing is ever finished; we should always consider things as merely evolving, so that we can strive to improve both ourselves and the projects we work on.

Using Radial Gradients

Our demo applied a linear gradient to the SVG image – it’s a perfectly valid option and works just as well. Trouble is, there may be occasions where this might not work so well; the base image may suit a gradient that radiates from a central point in the artwork.

To understand what we mean by this, take a look at the source image used earlier in Creating Unusual Shapes with Clip-Paths” – in a sense, I think the design would work better with a radial gradient than a linear one. In contrast, the image used in the previous demo has text that runs from left to right, so I suspect a radial one wouldn’t work so well (Figure 2-10), and that a linear one would be more suitable:
../images/461821_1_En_2_Chapter/461821_1_En_2_Fig10_HTML.jpg
Figure 2-10

Using a radial gradient instead...

Ultimately it is up to us to decide which fits our needs best – there is no hard-and-fast rule that determines which gradient should be used and when, so with that in mind, let’s test that assumption:

Change the <linearGradient tag to <radialGradient and save the change – the code should look like this:
<defs>
  <radialGradient id="wip-gradient" x1="0%" y1="0%" x2="100%" y2="0%">
  <stop offset="0%" style="stop-color:#FF9133;" />
  <stop offset="100%" style="stop-color:#FF0015;" />
  </radialGradient>
</defs>

Save the change – if we refresh the demo, it shows a change, as indicated in Figure 2-10 on the previous page. Something in me says this doesn’t look so good – it works, but the impact just isn’t quite there! Leaving this aside, our code uses a number of new keywords, so let’s take a moment to explore these in more detail.

Exploring How Our Code Works

Let’s revisit the core part of our code, from the first part of the gradient demo:
<defs>
  <linearGradient id="wip-gradient" x1="0%" y1="0%" x2="100%" y2="0%">
    <stop offset="0%" style="stop-color:#FF9133;" />
    <stop offset="100%" style="stop-color:#FF0015;" />
  </linearGradient>
</defs>

Our code was set up in a <defs> block – this allows it to be reusable throughout the SVG image. A closer look at the content of the code for the image shows multiple paths in use – we’ve already applied our gradient(s) to one of them, so they can be applied to the remaining paths in the same manner.

Within our definition, we have our <linearGradient> tags – alongside the standard ID, we have our coordinates (x1, y1 and x2, y2) and the <stop> attributes. The latter control the ramp of colors to use over the shape – in our case, we’ve specified 0% and 100%, so the gradient will run over the entire shape. If we had set something akin to 10% and 50% (for example), then the gradient will start from 10% in, and finish at 50% of the range.

I’d recommend changing the values as a test – this is the best way to experience the impact of changing the stop values on our design.

Taking It Further

It’s at this point I would normally suggest taking things up a notch, and taking a look at more advanced examples, such as that of the flame animation created by Sarah Drasner, at https://codepen.io/sdras/pen/gaxGBB .

However, I have a confession to make – and with good reason: Remember how I suggested trying to change the <linearGradient> tag to <radialGradient>, but not change any other value? Well, this has worked, but I’m not convinced it’s produced the best design – and not just because of the choice of colors!

The real reason is because of the coordinates we’ve specified in our shape – these are intended to be for linear gradients , whereas we should really be using cx, cy, and r to define the center and radius of the element. We should then use fx and fy values to define the focal point of our gradient – a mix of these values will very likely produce a gradient that has more impact than by simply replacing the tags as originally suggested at the end of the previous exercise.

To help gauge the impact of tweaking settings until you are more familiar with how they work, you may like to use an online gradient generator to help – there are several available online, such as the one available at the AngryTools.​com website: http://angrytools.com/gradient/ .

Enough of the confession – let’s move on! We’re not limited to simply creating SVG shapes to sit on a page; we can insert these into our page background as well. A good use case for this would be to create a company logo as an SVG image, then set the opacity to around 50%, and apply this as a fixed background image on our page. This is a really easy technique to get our heads around, so let’s dive in and explore this in more detail.

Applying Pattern Effects to CSS Backgrounds

Throughout the course of this chapter we’ve created a variety of shapes which can easily be added as images to a page – this works very well, but what if we needed to create a background effect ? Is this possible with SVG, you might ask….

Thankfully it is – Figure 2-11 shows that support for this feature in recent desktop browsers (last couple of years) is currently excellent:
../images/461821_1_En_2_Chapter/461821_1_En_2_Fig11_HTML.jpg
Figure 2-11

Support for SVGs in CSS backgrounds – Source: caniuse.​com

If we were to check the CanIUse.​com site , we will find that support among mobile devices is equally good, with only Opera Mini showing partial support in recent browsers. There is one question I do hear you ask though – why would we use a data-uri value to display our SVGs ? There are several benefits for using data-uris, when working with SVGs:
  • Data-uris can be stored within CSS files; this helps to reduce the number of calls to external resources, although this must be balanced against the size of our style sheet!

  • We can perform micro-optimization on data-uris, to a greater degree than we might on a standard SVG; this is a more advanced topic that we will cover in Chapter 7, “Optimizing SVGs”;

  • SVGs stored as data-uris can be manipulated internally, unlike external images (more anon).

Leaving aside the reasons for using data-uris for the moment, how does the process work? We can implement an SVG as a background image directly, but it makes it harder to change the fill color easily. In many cases, this won’t be an issue (or at least something we can live with), but there may be instances where we need to edit the color.

Fortunately, there are several ways to get around this: one such method is to use data-uris. Put simply, we convert our SVG image into a base-64 encoded string of characters, before adding it as a link within our style sheet.

Thankfully we don’t have to manually convert our image – after all, the conversions involved would be horrendous! We can instead make use of a convertor such as the example at https://codepen.io/elliz/pen/ygvgay , to facilitate this process for us. We’ll put this process to the test as part of our next exercise – this will make use of a pre-built SVG pattern , available from the Hero Patterns site, at http://www.heropatterns.com . Let’s dive in to see what is required in action.

ADDING A PATTERN

  1. 1.

    We’ll start by taking a copy of the gradients.html file from the previous exercise, then removing all of the code between the <body> tags – save this in our project folder as background.html.

     
  2. 2.
    Go ahead and add the following code in between the <body> tags of the file we’ve just created – don’t forget to save it:
    <div id="content">
      <h2>Beginning SVG: Applying SVGs to CSS Backgrounds</h2>
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus consequat mattis risus. Ut magna quam, consectetur a consectetur in, rhoncus ut diam. Curabitur mauris lectus, malesuada quis viverra in, tristique at est.</p>
      <p>Vestibulum in felis vitae eros aliquam ornare. Nunc elementum risus non neque rhoncus malesuada. Curabitur ultricies tellus eu sem sollicitudin, vel bibendum sapien sagittis. Duis scelerisque urna nulla, vel accumsan massa gravida commodo.</p>
    </div>
     
  3. 3.
    In a new file, add the following style code – this will format the text onscreen and provide a little styling for the panel containing the text. Save it as background.css, within the css subfolder of our project area:
    @font-face { font-family: 'pt_sansregular'; src: url('../font/pt_sansregular.woff') format('woff'); font-weight: normal; font-style: normal; }
    body { font-family: 'pt_sansregular', sans-serif; }
    #content { border: 0.0625rem solid #000; border-radius: 0.3125rem; width: 21.875rem; margin-left: auto; margin-right: auto; padding: 0.9375rem; background-color: rgba(255, 255, 255, .7); padding: 2rem; }

    Don’t forget to update the link to the CSS file in background.html!

     

Note the fonts folder should already be present in our project area from previous exercises.

  1. 4.

    Up next comes the real magic – we’re going to incorporate an SVG image into our background . For this, browse to http://www.heropatterns.com , then click on the Jupiter pattern.

     
  2. 5.

    Copy the contents of the Generated CSS Code box, then paste it immediately after the font-family:... line within the body style rule in our demo style sheet .

     
  3. 6.

    Save the style sheet – we can now preview the results! If all is well, we should see something akin to the screenshot shown in Figure 2-12.

     
../images/461821_1_En_2_Chapter/461821_1_En_2_Fig12_HTML.jpg
Figure 2-12

Applying SVG effects to CSS backgrounds

This little demo is meant to be very simple, but its simplicity belies the power of what we can achieve – the key lies in how we use a data-uri to display the image. Let’s take a moment to explore how our demo works in more detail, and see how we can adapt it for our own use.

Exploring the Code in Detail

Remember how we talked about the different ways of implementing SVG images, back in Chapter 1? Well, for many occasions, we would simply use <img> tags, treating our SVG image as if were a standard PNG or JPEG image, for example. However, we can also use background images, although the trade-off is that we lose the ability to style individual elements with the SVG image.

Our code doesn’t contain anything out of the ordinary, save for just one line – line 11. This is a call to background image: we treat our target image as if we are referencing one on available at a URL . However, instead of a URL, we have the code of our SVG as a string of characters; the code for this was provided by the Hero Patterns website, but it could equally have come from a convertor, such as the one available at https://codepen.io/elliz/pen/ygvgay . Once the code has been added to our style sheet, the results will be displayed when previewed within our browser.

Creating an Alternative Pattern

At this point, we’ve completed our demo – it looks great (at least for what it is) and works very well. This however is only part of the story: What about using some of the shapes we created right back at the start of this chapter?

Absolutely we can – the beauty of this is that we’ve already covered most of what we need to use to create it, save for one tag, the <pattern> tag:
    <svg width=125 height=120>
      <defs>
        <pattern id="illustration" x="10" y="10" width="20" height="20" patternUnits="userSpaceOnUse" >
          <circle cx="15" cy="15" r="15" style="stroke: none; fill: dimgray" />
        </pattern>
      </defs>
      <rect x="10" y="10" width="100" height="100" style="stroke: #000000; fill: url(#illustration);" />
  </svg>

To see how this works, go ahead and add this code to the background demo we’ve just created – it needs to go in immediately after the <h2>, on or around what will be line 12. We will also need to add in an svg { float: left; } to our style sheet, to allow text to flow around the SVG.

If we refresh the browser, we should see the updated version, as shown in Figure 2-13.
../images/461821_1_En_2_Chapter/461821_1_En_2_Fig13_HTML.jpg
Figure 2-13

Our updated SVG as a background image

Notice the difference – this gives us the ability to add in SVGs as patterns to a page; if we wanted to, we can simply extract the contents of the SVG into a string and replace the existing background URL with this new code. Suffice to say that this gives us plenty of options when creating our projects!

It’s time to change tack – we’ve almost come to the end of this chapter, but before we move onto exploring images and text, there is one more topic we need to cover. We’ve touched on a variety of different techniques for creating shapes; unfortunately, there is not enough space in this book to print all of the available configuration options we can use to manipulate these shapes. There are, however, plenty of good resources available, so let’s take a moment to cover off some of the more useful ones as a starting point for developing your skills with SVG.

Setting Advanced Configuration Options

Over the course of this chapter, we’ve encountered a host of different attributes for manipulating different elements – such as the x1,y1 coordinates, or stroke-width for setting the width of the border on an SVG. Trouble is, we’ve only scratched the surface: detailing all of the possible options would easily fill a book by itself!

With this in mind, I would definitely encourage you to make use of available online resources that detail these and more advanced configuration options; some of them are listed below, to help get you started:

There are plenty more articles available online – note though that some are a few years old, so if in doubt, I would recommend checking the commands used against the MDN articles listed above, which are regularly updated and present a useful source of the attributes available when working with SVG elements.

Summary

Creating an SVG design consists of using a mix of different shapes – this might range from the humble square through to something that can perhaps only be described as being abstract. Clearly choosing the right mix of shapes to use will determine how easy or complex our final design is to create – we’ve covered a number of options throughout the course of this chapter, so let’s take a moment to review what we’ve learned.

We kicked off this chapter with a review of the different types of shapes available, which included squares, circles, and lines; in each instance we created a simple example, before working through the different attributes that made up the code.

Next up came a look at creating more advanced or unusual shapes – we saw how paths can play a key part in rendering what is effectively a series of connected points in our design. We also took a look at how we might paint our designs: we covered how this has already been done in the examples thus far but also explored some of the other options available to us.

We then rounded out this chapter with a dive into exploring how SVG can be used to create patterns and gradients – this might be repeating a simple shape, through to something more complex such as a linear or radial gradients.

Phew – what a monster chapter! We’re only just getting started though on our journey through the world of SVG: We’ve created shapes, but what about images and text? We can create some great effects using SVG in this respect, so stay tuned to see how in the next chapter…

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.149.248.0