051 SVG

27 Sep 2013

SVG or Scalable Vector Graphics is a language for describing two-dimensional graphics in XML. In this episode, we will explore various ways to draw different shapes, filters and gradients with SVG ending off with a little addition of interactivity by manipulating the SVG with JavaScript.

Download video: mp4

Sample code: Github

Version: SVG 1.1

Similar episodes: 014 Local Web Servers, 050 DOM

Background on SVG

  1. Specification - W3C Recommentation
  2. SVG tutorial by MDN
  3. SVG tutorial by Web Platform
  4. SVG tutorial by Hong Kiat - why use SVG?

Things to learn with SVG

simple svg

  1. read the SVG specification
  2. mime type image/svg+xml with extension *.svg
  3. create a file index.html with a simple embedded svg

    <!doctype html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
      <title>SVG</title>
    </head>
    <body>
    
    <svg>
      <line x1="0" y1="0" x2="200" y2="0" stroke-width="10" stroke="rgb(0,0,0)"/>
    </svg>
    
    </body>
    </html>
    
  4. create another file called line.svg with similar contents. add on attributes for the tag svg

    <svg version="1.1" baseProfile="full" width="300" height="200" xmlns="http://www.w3.org/2000/svg">
      <line x1="0" y1="0" x2="200" y2="0" stroke="black" stroke-width="10" />
    </svg>
    

    and amend the file index.html's body tag

    <img src="line.svg" >
    

    slant the line in the file line.svg by changing the value of y2

    <line x1="0" y1="0" x2="200" y2="50" stroke="black" stroke-width="5" />
    

    amend the image size in the file index.html

    <img src="line.svg" width=400>
    

shapes and styling

all the below-mentioned code are embeded within the tags svg

  1. line

    slanted line

    <line x1="0" y1="100" x2="200" y2="0" stroke-width="10" stroke="rgb(0,0,0)"/>
    
  2. polyline

    <polyline points="0,50 50,50 60,100 110,100 120,150" style="fill:wheat;stroke:cornflowerblue;stroke-width:5;"/>
    
  3. rectangle

    starting from origin

    <rect width="400" height="100" style="fill:darkseagreen;stroke-width:5;stroke:black"/>
    

    starting from another position

    <rect x="100" y="100" width="400" height="100" style="fill:darkseagreen;stroke-width:5;stroke:black"/>
    

    curved corners

    <rect x="50" y="20" rx="20" ry="20" width="300" height="100" style="fill:rgb(0,0,255);stroke-width:5;stroke:rgb(0,0,0)"/>
    
  4. circle

    simplest

    <circle r="100" fill="hotpink"/>
    

    position starting from another place

    <circle r="100" cx="100" cy="100" fill="hotpink"/>
    

    with stroke

    <circle r="100" cx="150" cy="150" fill="hotpink" style="stroke:black; stroke-width:5;" />
    
  5. ellipse

    <ellipse cx="300" cy="80" rx="200" ry="50" style="fill:lightskyblue;stroke:midnightblue;stroke-width:5"/>
    
  6. polygon

    <polygon points="0,90 45,12 135,12 180,90 135,168 45,168" style="fill:linen;stroke:maroon;stroke-width:15"/>
    
  7. path - specification

    <path d="m 10 10 l 150 0 m 30 30 l 150 0" stroke="mediumvioletred" stroke-width="3" fill="none" />
    

    curves

    <path d="m 100 250 s 100 -125 400 40" stroke="steelblue" stroke-width="5" fill="none" />
    
  8. text

    <text x="200" y="200" style="fill:saddlebrown;font-size:10em;">SVG</text>
    

filters

referenced elements be defined inside of a defs element

<svg>
    <defs>
    <filter id="fading">
        <feGaussianBlur in="SourceAlpha" stdDeviation="5" />
    </filter>
    </defs>
    <rect x="100" y="100" width="400" height="100" style="fill:darkseagreen;" filter="url(#fading)"/>
    <rect x="95" y="95" width="400" height="100" style="fill:darkseagreen;stroke-width:5;stroke:black" />
</svg>

gradients

<svg>
    <defs>
    <linearGradient id="sunrise" x1="0%" y1="0%" x2="0%" y2="100%">
        <stop offset="0%" style="stop-color:red;stop-opacity:1" />
        <stop offset="50%" style="stop-color:orange;stop-opacity:1" />
        <stop offset="100%" style="stop-color:yellow;stop-opacity:1" />
    </linearGradient>
    </defs>
    <circle r="100" cx="120" cy="120" fill="url(#sunrise)" />
</svg>

building the project

  1. create a file index.html with h1 and its styling. open the file through a local web server and view it in the browser with the url example http://localhost:8000

    <!doctype html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
      <title>SVG</title>
      <style>
      body{margin: 1em auto; width: 610px;}
      h1 {
        font-family: Helvetica Neue, sans-serif;
        font-size: 4em;
        display: inline-block;
        vertical-align: top;
        margin: 0;
      }
      </style>
    </head>
    <body>
    
    <h1>Water Molecule</h1>
    </body>
    </html>
    
  2. download an svg from the noun project and play with it in the browser

  3. link it as an image to the current file index.html

    <img src="lab.svg">
    

    make the image bigger/small

    <img src="lab.svg" width=400>
    

    add a class to it

    ...
    .small {
      margin: 0 0 0 20px;
      height: 70px;
    }
    ...
    <img src="lab.svg" class="small">
    ...
    
  4. create svg covalent.svg, 3d.svg and link it

    <section><img src="covalent.svg"></section>
    <section><img src="3d.svg" id="water"></section>
    
  5. for covalent.svg

    • create the <circle> for the various atomic shells
    • create the embedded css styling
    • grouping the red and green pairing electrons with the tag <g>
    • styling the red and green electrons
    • create the text
  6. for 3d.svg

    • create the 3 molecules with <circle>
    • create the radial gradients
    • grouping the red and green pairing electrons with the tag <g>
    • styling the red and green electrons
    • create the text
  7. add scripts to manipulate the file 3d.svg upon clicking

    • amend to object tag instead of img

      <section>
        <object type="image/svg+xml" data="3d.svg" id="water"></object>
      </section>
      
    • add scripts to the file index.html - with a click it will change the size of the oxygen molecule

      <script>
      var svg = document.getElementById("water");
      console.log(svg);
      
      svg.addEventListener("load",function(){
        var svgDoc = svg.contentDocument;
        var oxygen = svgDoc.getElementsByTagName('circle')[2];
        oxygen.addEventListener("click",function() {
      
          if(oxygen.getAttribute('r') ==  100) {
            console.log('Inside: ' + oxygen);
            oxygen.setAttribute('r', 95);
          }
          else {
            oxygen.setAttribute('r', 100);
          }
        });
      });
      </script>
      

More Resources on SVG

  1. Using SVG
  2. Can i use SVG
  3. RaphaelJS
  4. Resolution Independence With SVG
  5. Inkscape - open source vector graphics editor
  6. SVG example with an animated eyeballs

Credits

  1. The Noun Project - Lab icon

Build Link of this episode

Nodeschool.io - interative command line based lessons made with Workshopper