Free Trial

Safari Books Online is a digital library providing on-demand subscription access to thousands of learning resources.

  • Create BookmarkCreate Bookmark
  • Create Note or TagCreate Note or Tag
  • PrintPrint
Share this Page URL
Help

4. Hacking Your Graphics with Canvas and... > Hack 44. Animate Illustrations with ...

Hack 44. Animate Illustrations with SVG

Easily turn your SVG illustrations into SVG animations by adding a few lines of HTML or CSS. That’s right, no JavaScript is necessary for this easy animation.

Before HTML5, animation was cumbersome. It was never intended to be done on the Web, which might be why developers worked so hard to make it happen. Before HTML5, all animation had to be done with JavaScript. It took us back to the days of stop-frame animation where we had to move the object being animated one frame at a time. With JavaScript, we would slowly change the attribute we were trying to animate one or two pixels at a time. Whether it was height (to make a window slide open) or position (to animate something across the screen), JavaScript would repetitively alter the style attributes until the “animation” was complete. As you can imagine, it wasn’t only code-heavy, but processor-heavy as well.

Along comes SVG, bringing with it some easy-to-perform, hardware-accelerated animations. In this hack we’ll look at two animation options in our SVG tool belt.

The SVG <animateMotion> Tag

SVG is completely XML-based. So it only makes sense that it has a tag for animation. Let’s start with a simple box and bouncing ball. This requires only a few lines of SVG:

<svg version="1.1"
     baseProfile="full"
     xmlns="http://www.w3.org/2000/svg">

    <rect x="100" y="0" width="400" height="100"  fill="pink"
     stroke="black" stroke-width="1" />
    <circle cx="120" cy="50" r="20" fill="blue" stroke="black"
     stroke-width="1" />
  </svg>

From this code we end up with a rectangle with a circle inside it (see Figure 4-22).

SVG elements without any animation
Figure 4-22. SVG elements without any animation

In order to animate this ball moving from one side of the rectangle to the other, we will add a new tag and nest it inside the circle element, as a child element (think of it as a command associated with the circle element). Let’s look at our new SVG and then we will walk through the details of the new tag:

<svg version="1.1"
     baseProfile="full"
     xmlns="http://www.w3.org/2000/svg">

    <rect x="100" y="0" width="400" height="100"  fill="pink"
    stroke="black" stroke-width="1" />
    <circle cx="120" cy="50" r="20" fill="blue" stroke="black"
    stroke-width="1">
      <animateMotion path="M 0 0 H 380 Z" dur="3s"
      repeatCount="indefinite" />
    </circle>
  </svg>

This new animateMotion tag allows us to animate the circle element while all other elements stay fixed. In this tag we are utilizing three attributes:

path

The path is the hardest part of this tag. It appears to be a random list of numbers and letters that somehow give us a perfect path from one end of the rectangle to the other. This path is actually a wrap-up of our motion command. Breaking it down, the M represents the command to “move to” a new location, the 0 0 is the x,y start position, and H tells it to move horizontally. From there, 380 is the distance it should move measured in points, and the Z command closes the path and tells it to start back at the beginning. This notation is all part of the SMIL (Synchronized Multimedia Integration Language) Specification, the details of which you can access on the W3C website.

dur (duration)

This attribute defines how long it will take to complete a full path. Values are represented in seconds with the format of 3s.

repeatCount

This attribute defines how many times the path will “repeat.” Don’t be fooled by the word repeat; a value of 1 will run the path only once, and a value of 5 will run the path five times. In our case, we set it to indefinite, so it will run until the page is closed or the value is changed.

Our ball will now bounce back and forth within the rectangle. With SVG, animation is at the root of the language. Just as any other component becomes a value in the DOM, so does our <animation> tag, and it can be accessed and altered with JavaScript. Figure 4-23 shows a view of our end product.

SVG animating the ball back and forth inside the box with only one line of code
Figure 4-23. SVG animating the ball back and forth inside the box with only one line of code

Flexibility in Structure

In our first example, we made the <animation> tag a child tag to the element that was being animated. In many cases you may have a group of tags that you want to animate. To address such situations we will pull out some code from a previous hack of our smiley face created in SVG. If we want to animate this smiley face back and forth on the screen, we certainly don’t want to have to animate each element separately. This would be both time-consuming to code and intensive on our processor, as the engine would be calculating each element separately. Let’s look at two different code samples showing how to animate a group of SVG tags together.

Here is our first sample:

<svg version="1.1"
     baseProfile="full"
     xmlns="http://www.w3.org/2000/svg">
  <g>
  <circle cx="300" cy="164" r="160" fill="yellow" stroke="black"
  stroke-width="2" />
  <circle cx="210" cy="100" r="20" fill="black" />
  <circle cx="380" cy="100" r="20" fill="black" />
  <clipPath id="MyClip">
    <rect x="30" y="200" width="600" height="100" />
  </clipPath>
  <circle cx="300" cy="160" r="120" fill-opacity="0" stroke="black"
  stroke-width="5" clip-path="url(#MyClip)" />
  <animateMotion path="M 0 0 H 300 Z" dur="3s"
  repeatCount="indefinite"></animateMotion>
  </g>
</svg>

Here is our second sample:

<svg version="1.1"
     baseProfile="full"
     xmlns="http://www.w3.org/2000/svg">
  <animateMotion path="M 0 0 H 300 Z" dur="3s" repeatCount="indefinite">
  <circle cx="300" cy="164" r="160" fill="yellow" stroke="black"
  stroke-width="2" />
  <circle cx="210" cy="100" r="20" fill="black" />
  <circle cx="380" cy="100" r="20" fill="black" />
  <clipPath id="MyClip">
    <rect x="30" y="200" width="600" height="100" />
  </clipPath>
  <circle cx="300" cy="160" r="120" fill-opacity="0" stroke="black"
  stroke-width="5" clip-path="url(#MyClip)" />
  </animateMotion>

</svg>

In the first sample we had a parent element to our code, named g, which is code for “group”. Once we group our code together, it’s treated as one element (on that level) and our <animateMotion> tag simply becomes another child tag to the g element whose job is to animate the group of elements.

In the second sample, instead of introducing the new tag we simply use the <animateMotion> tag as a parent to enclose the tags that produce the smiley face. The <animateMotion> parent tag animates the tags nested inside it as a group, and the process is streamlined significantly as compared to animating each element individually.

One Last Option

Don’t you just love SVG? Just like HTML, there is always more than one way to accomplish everything. This flexibility allows you to pick the method that works best in your particular situation. With SVG animation, there is no shortage of options.

Keeping in mind that SVG elements become DOM elements just like any other HTML page elements, we can animate our SVG just as we would HTML, by using CSS. In the preceding sample that introduced the g element, we can remove the <animateMotion> tag completely, and set an id on the g element. From here, we can use a CSS3 transform to create the same animation. For more on applying CSS to SVG elements, see [Hack #43].

  • Safari Books Online
  • Create BookmarkCreate Bookmark
  • Create Note or TagCreate Note or Tag
  • PrintPrint