Scalable Vector Graphics Primer - Web Animation using JavaScript: Develop and Design (2015)

Web Animation using JavaScript: Develop and Design (2015)

Chapter 6. Scalable Vector Graphics Primer

Since an in-depth tutorial on Scalable Vector Graphics (SVG) could easily comprise a book of its own, this chapter simply serves as an introduction to the topic. The goal is to equip you with enough knowledge to be comfortable animating SVG elements and to know where to go next to continue your learning.

Creating images through code

An SVG element is a type of DOM element that borrows the syntax of the HTML elements you’re already familiar with to define arbitrary shapes. SVG elements differ from HTML elements in that they have unique tags, attributes, and behaviors that allow them to define graphic shapes. Put another way, SVGs let you to create images through code. This is a tremendously powerful concept because it means you can programmatically style and animate these shapes using JavaScript and CSS. In addition SVG offers many other benefits:

Image SVG compresses incredibly well. Graphics defined in SVG have smaller file sizes than their PNG/JPEG equivalents, which can greatly improve site load times.

Image SVG graphics scale to any resolution without a loss of clarity. Unlike standard image formats, they look razor sharp across all devices—say good-bye to blurry images on mobile screens.

Image Like HTML elements, SVG elements can be assigned event handlers that respond to a user’s input, which means that the graphics on your page can be made interactive. If you so desired, all the buttons on your site could be turned into animated graphics.

Image Many photo-editing apps (including Adobe Photoshop, Sketch, and Inkscape) let you export your design work into SVG format for quick copying and pasting into HTML. So, even if you don’t consider yourself an artist, you can leverage third-party applications to do the designing for you.

In short, SVGs are an amazing graphics solution. Let’s dive in!

SVG markup

SVG elements are defined within a parent <svg> container. Specifying the width and height dimensions of container element defines the canvas that your SVG graphics render upon:

<svg version="1.1" width="500" height="500" xmlns="http://www.w3.org/2000/svg">
<circle cx="100" cy="100" r="30" />
<rect id="rect" x="100" y="100" width="200" height="200" />
</svg>

Within <svg>, you can insert SVG shape elements of varying sorts. The above example has a circle element followed by a rect (rectangle) element. As with normal HTML elements, SVG elements accept height and width attributes, which are used here for demonstration purposes, but (as with HTML) it’s considered best practice to specify SVG styling properties within a CSS stylesheet. Also as with HTML, stylesheet classes target SVG elements via their id, class, or tag types.

Where the SVG and HTML specifications fundamentally differ is in their range of accepted HTML attributes and CSS properties. SVG elements accept only a few of the standard CSS properties. Further, SVGs accept a special set of attributes, called presentational attributes, which include fill, x, and y. (fill specifies which color to fill a shape with, whereas x and y define the position of the element’s top-left corner.) These attributes define how an element is visually rendered on its canvas. Let’s run through a few of them, using rect as a sample SVG element:

<rect id="rect" x="100" y="100" width="200" height="200" />

Here, the width and height attributes work as you’d expect. The unique x and y attributes define the rectangle’s coordinates within the canvas. These values simply position the rectangle relative to an x = 0, y = 0 origin point. Unlike HTML, SVG positioning is not defined with top,right, bottom, left, float, or margin CSS properties; SVG positioning logic is fully dictated by explicitly defined coordinates. In other words, an SVG element’s positioning doesn’t affect the position of its sibling elements; instead of pushing each other around the page, SVG siblings simply overlap one another.

Now let’s take a look at the circle element. Its rendering is specified via coordinates that designate its center point (cx and cy) along with a radius value (r) that designates its length:

<circle cx="100" cy="100" r="30" />

Pretty simple, right? SVG elements use the same markup structure as HTML elements, so all the code samples in this chapter should feel familiar.

Note that there are many other types of SVG elements, including ellipse, line, and text. See the end of this chapter for further details.

SVG styling

SVG elements accept a variety of special styling properties that are not available to HTML elements. SVG’s fill property, for example, is similar to background-color in CSS, stroke is similar to border-color, and stroke-width is similar to border-width. Take a look at this example:

<svg version="1.1" width="500" height="500" xmlns="http://www.w3.org/2000/svg">
<circle cx="100" cy="100" r="30" style="fill: blue" />
<rect id="rect" x="100" y="100" width="200" height="200" style="fill: green; stroke: red; stroke-width: 5px" />
</svg>

Above, the circle element is filled with solid blue, and the rect element is filled with solid green. Additionally, the rectangle has a red border with a thickness of 5px.

There are many other SVG-specific styling properties. For now, it’s simply important for you to know that they exist so you’ll pay extra attention when trying to animate CSS properties on SVG elements.


Image Note

Refer to the “Wrapping up” section of this chapter for information on where to find a full listing of SVG styling properties.


Support for SVG

Out-of-the-box support for SVG element animation isn’t great: neither jQuery nor CSS offers complete support for animating SVG-specific styling properties and presentational attributes. Further, CSS transitions can’t animate SVG elements at all on Internet Explorer 9, and CSS can’t be used to apply transform animations to SVG elements on any version of Internet Explorer.

To gain comprehensive SVG animation support, use either a dedicated SVG library or an animation library that has built-in support for SVG elements. One noteworthy dedicated SVG library is Snap.svg. It probably won’t surprise you to learn that Velocity.js, the JavaScript animation library you’ve been using throughout this book, provides full support for SVG element animation.


Image Note

Go to SnapSVG.io to download the Snap.svg library.


SVG animation

SVG elements might never be the backbone of your UI, but they’re certainly appropriate for spicing up the parts of your page that you’d normally fill with static images. Uses for SVGs include:

Image Buttons with intricate animation sequences that are triggered when users hover and click.

Image Unique loading status graphics that replace the all-too-common rotating indicator GIF.

Image Company logos whose individual parts animate together upon page load.

This last use case is explored in more detail later in this chapter.

Passing in properties

With Velocity, SVG properties are animated in the same way that standard CSS properties are. Pass the appropriate properties and their desired end values into Velocity’s properties object:

// Animate an SVG element to a red fill and a black stroke
$svgElement.velocity({ fill: "#ff0000", stroke: "#000000" });

In contrast, note that the code below would not work since the following CSS properties are not supported by SVG elements:

// Incorrect: These properties don't apply to SVG elements
$svgElement.velocity({ borderSize: "5px", borderColor: "#000000" });

Presentational attributes

The presentational attributes explored earlier in this chapter are also animated as expected:

// Animate the x and y coordinates of a rectangle
$("rect").velocity({ x: 100, y: 100 });
// Animate the cx and cy coordinates of a circle
$("circle").velocity({ cx: 100, cy: 100 });
// Animate the dimensions of a rectangle
$("rect").velocity({ width: 200, height: 200 });
// Animate the radius of a circle
$("circ").velocity({ r: 100 });

All the Velocity features that you’re currently using—animation reversal, UI pack effects, sequence triggering, and so on—also work as expected with SVG elements.

Positional attributes vs. transforms

You might be wondering what the difference is between using the x, cx, y, and cy positional attributes instead of CSS transforms (e.g. translateX, translateY) when specifying the positions of SVG elements. The answer is browser support. Internet Explorer (up to and including Internet Explorer 11) does not support CSS transforms on SVG elements. Consider the following:

// The x and y attributes work everywhere that SVG elements do (IE8+, Android 3+)
$("rect").velocity({ x: 100, y: 100 });
// Alternatively, positional transforms (such as translateX and translateY) work everywhere *except* Internet Explorer
$("rect").velocity({ translateX: 100, translateY: 100 });


Image Note

Although transforms are known to be particularly performant due to hardware acceleration (read more on this in Chapter 7, “Animation Performance”), both approaches to SVG animation are equally fast since SVG graphics are hardware-accelerated by default.


Image

Implementation example: Animated logos

High-resolution site logos that animate into place upon page load are ideal targets for SVG implementation. Suppose you want to crudely replicate the MasterCard logo, which consists of two overlapping circles of different colors. If you were to animate this logo into place using Velocity, you’d start with an SVG canvas defined as follows:

<svg version="1.1" width="500" height="500" xmlns="http://www.w3.org/2000/svg">
<circle id="circleLeft" cx="100" cy="100" r="30" style="fill: red" />
<circle id="circleRight" cx="100" cy="100" r="30" style="fill: orange" />
</svg>

This creates two overlapping circles with identical radii. Next, you’d animate the circles outward from their origins so that they overlap only slightly when they’re done animating:

// Move one circle toward the left
$("#circleLeft").velocity({ cx: "-=15px" }, { easing: "spring" });
// Move one circle toward the right
$("#circleRight").velocity({ cx: "+=15px" }, { easing: "spring" });

Here, the left circle is animated 15 pixels leftward (using the "-=" operator to instruct Velocity to decrement the circle’s current value) and the right circle is animated 15 pixels rightward. The spring easing provides added flair by making the circles bounce away from one another with propulsive force.

Since SVG elements can listen for mouse-based events (clicks, hovers, and so on), you could improve upon this demo by turning it into an example of SVG element interaction. With the aid of jQuery and Velocity, one such implementation could look like this:

$("svg").on("mouseover mouseout", function() {
$("#circleLeft, #circleRight").velocity("reverse");
});

This triggers a reversal of the circles’ page-load animation when the user hovers on or off the SVG element. The single line of code accomplishes this by leveraging Velocity’s reverse animation command. For more on working with reverse, refer to Chapter 2, “Animating with Velocity.js.” In effect, when the user first hovers, the page-load animation is reversed. When the user then hovers off, the reversal is itself reversed, bringing the logo back to its original form.

While this code example is undoubtedly anticlimactic, this is once again a good thing because it reflects the similarities between animating SVG and HTML elements. Where SVGs do start to become uniquely complex is when you define arbitrary shapes that go beyond the basics of squares, rectangles, circles, and so on. After all, SVG elements can define any shape you can dream up in a photo editor, so they have to be tremendously expressive. And they are. But mastering SVG design is beyond the scope of this book. See the “Wrapping up” section of this chapter to learn where to go next to continue learning.

Wrapping up

If you’re intrigued by what you’ve read so far and want to learn more about working with SVGs, check out these great resources:

Image For a full overview of working with SVG elements, refer to Joni Trythall’s fantastic and free SVG Pocket Guide (https://github.com/jonitrythall/svgpocketguide).

Image For a directory of SVG element types and their properties, consult Mozilla Developer Network (https://developer.mozilla.org/en-US/docs/Web/SVG).

Image For a listing of all the SVG attributes and styling properties that Velocity can animate, refer to VelocityJS.org/#svg.