post-thumb

SVG Part 2 - Dynamic vector graphics

This second post focuses on a less known aspect of the SVG standard: it’s dynamic capacities!

In the previous post of this series we discovered that SVG is a XML-based format compatible with DOM and CSS standards. SVG graphic elements can therefore by manipulated by JavaScript code through the DOM and styled with CSS.

After showing how to mix SVG and HTML, this post focuses and how to animate SVG elements, with three different methods: pure SVG instructions, CSS and JavaScript.

Mixing HTML and SVG

One of the advantages of SVG is that it can be mixed or nested with other XML languages, such as HTML5 or XHTML for example.

It is possible to mix HTML and SVG elements in the same XML document using different namespaces. Even better this allows to interact with SVG objects from JavaScript code included in the HTML page.

<html xmlns="http://www.w3.org/1999/xhtml" 
 xmlns:svg="http://www.w3.org/2000/svg">
<body>
  <h3>SVG nested in XHTML</h3>
    <svg xmlns="http://www.w3.org/2000/svg" 
     width="300" height="140">
      <circle id="monDessin" 
       cx="70" cy="70" r="40"
       stroke="black" 
       stroke-width="2" 
       fill="red "/>
    </svg>
  <div>Nesting is possible through the use of namespaces</div>
</body>
</html>

SVG in a XHTML document

Scripting and events

SVG implements the W3C DOM standard and is therefore manipulable via JavaScript in a similar way to X/HTML. Each element and attribute of an SVG document can be dynamically modified.

Furthermore SVG has an event system similar to X/HTML. Classic events like onload, onunload, onclick, omouseup, onmousedown, onmouseover, onmousemove, onmouseout… are available. But also specific events related to animations: onbegin, onend, onrepeat.

The following example changes the color of an SVG element when clicked:

<html xmlns="http://www.w3.org/1999/xhtml" xmlns:svg="http://www.w3.org/2000/svg">
  <body>
    <h3>Click the circle to change its color</h3>
    <svg xmlns="http://www.w3.org/2000/svg" width="300" height="200">
      <circle id="myCircle" 
       cx="70" cy="70" r="40"
       stroke="black" 
       stroke-width="2" 
       fill="red"/>
      <script>         
      <![ CDATA[
        function doClick(e) {
          document.getElementById("myCircle")
                  .setAttribute("fill", "blue");
        }
        document.getElementById("myCircle")
                .onclick = doClick;
        ]]>
      </script>
    </svg>
  </body>
</html>

Image description

If you want to play with this example use Codepen below:

SVG Animations

The SVG standard also contains animations by modifying the attribute values of an element (or groups of elements).

SVG uses time-based animations and not frame-based ones as some other technologies. It is therefore necessary to indicate the start and duration of each animation, which can then vary any SVG attribute. Animations can also run in parallel and be triggered by user events.

Several tags are dedicated to animations:

  • animate: variation of an attribute over time
  • set: simple modification of an attribute for a specified duration
  • animateColor: color transition over time
  • animateMotion: moving the element along a path (cf. path tag described above)
  • animateTransform: control of the application of SVG transformations on the element (cf. transform tag above)

Example: change x value

<text x="10" y="10">Change x value</text>
<rect 
 x="10" y="30" 
 width="200" height="100"
 style="fill:#CCCCFF; stroke:#000099">
  <animate 
   attributeName="x" attributeType="XML" 
   begin="0s" dur="5s" 
   from="10" to="150" fill="freeze"/>
</rect>

Animation: change x value

On Codepen:

Example: change visibility

<text x="10" y="10">Change visibility</text>
<rect 
 x="50" y="50" 
 width="200" height="100"
 style="fill:#CCCCFF; stroke:#000099"
 visibility ="hidden">
  <set 
   attributeName="visibility" 
   attributeType="XML"
   begin="2s" dur="3s" 
   to="visible"/>
</rect>

Change visibility

On Codepen:

Example: change color with motion

<text x="10" y="10">Change color with motion</text>
<rect 
 x="50" y="50" 
 width="200" height="100" 
 style="stroke:#000099">
  <animate 
   attributeName="fill" 
   from ="red" to="blue" 
   dur="4s" fill="freeze"/>
  <animateMotion 
   dur="6s" 
   path="M10 10 L 100 50" 
   rotate="auto"/>
</rect>

Animate color with motion

On Codepen:

In the previous examples, animations are triggered after a certain number of seconds, specified via the begin attribute. It is also possible to associate this trigger with a user event, for example with begin=‘mouseover’.

More complex animations can be achieved by parallelizing simple animations. The animations have many more parameters to control their timeline and sequences, they are not detailed here for the sake of conciseness.

CSS Animations

SVG elements can be styled by inline or external CSS instructions. This means that they can also be modified with classic CSS animations and transitions .

For instance let’s use CSS to ease the change of color of our rectangle when hover:

<text x="10" y="10">Change color with CSS</text>
<rect id="myRect" 
 x="10" y="30" 
 width="200" height="100"/>
#myRect { 
  fill: #CCCCFF; 
  stroke: #000099; 
  transition: fill 2s ease-out;
}
#myRect:hover { 
  fill: #4e86b1; 
}

Here is another example using CSS transformations.

<svg>
  <rect class="top" 
   x="20" y="29" 
   width="60" height="7.85106" 
   fill="#000" />
  <rect class="middle" 
   x="20" y="45.5745" width="60" 
   height="7.85106" 
   fill="#000" />
  <rect class="bottom" 
   x="20" y="62.1489" 
   width="60" height="7.85106" 
   fill="#000" />
</svg>
svg {
  cursor: pointer;
}

rect {
  transition: all 0.3s ease-in-out;
}

svg:hover .top {
  transform: rotate(45deg);
  transform-origin: center top;
  x: 50px;
  y: 35px;
}

svg:hover .middle {
  x: 0;
  opacity: 0;
}

svg:hover .bottom {
  transform: rotate(-45deg);
  transform-origin: center top;
  x: -20px;
  y: 25px;
}

Result on Codepen:

JavaScript Animations

They are several JavaScript libraries simplifying SVG creation and animation, like for instance D3.js , Chart.js , Velocity.js or Raphaël .

Let’s play with snap.svg . It is a complete rewrite of Raphaël by its original author, who now work for Adobe (yes the company who created Flash! The circle is complete).

One interesting feature is the ability to work with existing SVG.

Example of dynamic text animated with snap.svg

Declare a empty SVG element in the webpage:

<svg id="svg" width="100%" height="400" 
 version="1.1" xmlns="http://www.w3.org/2000/svg">
</svg>

Import the snap.svg library and use it to create the text animation:

var s = Snap("#svg"); 
var text = 'Dynamic text animated with snap.svg';

var textArray = text.split(" ");
var len = textArray.length;
var timing = 750;

for( var index=0; index < len; index++ ) {
  (function() {
    var svgTextElement = s.text(
      350,
      100, 
      textArray[index]
    ).attr(
      { 
        fontSize: '120px', 
        opacity: 0, 
        "text-anchor": "middle" 
      }
    );
    setTimeout( function() {
      Snap.animate( 0, 1, function( value ) {
        svgTextElement.attr(
          { 
            'font-size': value * 100,  
            opacity: value 
          }
        );
      }, timing, mina.bounce, function() { 
        svgTextElement.remove() 
      });
    },index * timing)
  }());
};

In Codepen (click on the Rerun bottom-right button if you missed the animation):

Advanced example of snap.svg mascot animation

Animation tools

It is also possible to use specific editors to create SVG animation. They are different from static SVG editors like Inkscape or adobe Illustrator. They usually use all or part of the previous techniques to animate SVG documents.

Here are some examples of such tools:

  • Adobe Animate supports import/export of SVG files and animations
  • SVGator is an online tool dedicated to SVG animations
  • SVG Artista , an open source online editor, proposes to apply a few CSS animations on an existing SVG document

SVG Gator screenshot

Static SVG documents are not always optimized when they are created or exported from various editors. The SVGO tool (for SVG Optimizer) is very useful to get rid of useless or redundant information from such SVG files.

Conclusion

SVG is a powerful language and technology, supported by all recent browsers but is underestimated and not exploited to its full potential. In addition to the lack of support for audio and preload support, its other downside is that it’s too often reduced to a static graphic format.

Let’s hope recent and mainstream animation tools and frameworks will support its dynamic capacities and make Dynamic SVG more visible and adopted.