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 42. Build “Native” Illustration...

Hack 42. Build “Native” Illustrations with Scalable Vector Graphics

Scalable Vector Graphics (SVG) is usually the most “familiar” graphics format in the HTML5 family of technologies. This hack will quickly get you working with the SVG format as though it were part of the DOM (hint: it really is part of the DOM!).

Scalable Vector Graphics is the W3C’s recommendation for web illustrations. Similar to Flash, SVG is a markup language for describing two-dimensional vector graphics, but it’s an open XML-based language as opposed to being proprietary. Think of SVG as being the graphical equivalent to HTML, and like HTML, SVG works seamlessly with other browser technologies such as JavaScript, CSS, and the DOM.

Why SVG?

Compared to all the other graphics and media-based technologies introduced in HTML5, SVG has some major advantages. The primary advantage is the technology itself. Being an XML-based language, SVG doesn’t require an editing program like Flash, Photoshop, or even Paint. You can create and edit SVG images with any simple text editor, or with your favorite web editor. The S in SVG stands for Scalable, and scalable it is! SVG is resolution-independent. Your SVG images can be zoomed in or out, and even printed at any size, and they will still maintain their quality, which is the primary benefit of the technology.

Being pure XML, SVG is natively searchable, indexable, and easily compressible. It’s also quite natural to embed text within your SVG files and then style them with CSS. It’s also easy to make SVG graphics compliant with the Americans with Disabilities Act (ADA), by embedding descriptions of the images within the SVG file itself.

Creating Your SVG Image

In most cases SVG is managed in its own file. This is a text-based file ending with .svg. You would then embed that file into the DOM in a manner similar to how you would work with an image. In our example, we’ll start with a new SVG file named smiley.svg and embed it into our sample page with the following code:

<object data="smiley.svg" type="image/svg+xml" />

Technically, our SVG file is an object on the page, not an image, and therefore is embedded with an object file. At this point we will see our object in the DOM, but it will not display anything, as the SVG file is blank. But we will fix that.

Now, to really impress our friends and enemies we’ll build an SVG object that demonstrates the cross-cultural symbol for love, peace, and hope: the smiley face.

Drawing with XML

Unlike a JPEG or PNG image, where the image is transmitted in Unicode, an SVG image is drawn out by a series of rules that follow the XML schema. This tends to make the images lightweight and ultra-scalable. In the preceding code example, we created an object element that has a data attribute pointing to an SVG file. This SVG file contains a few lines of code that draw out our smiley face. Before we start, let’s see how our end product will look (see Figure 4-18).

The smiley face SVG image represented in our sample web page template
Figure 4-18. The smiley face SVG image represented in our sample web page template

This cheeky smiley face is truly simple. The SVG file consists of only five elements, and each element becomes a discrete DOM element once it’s imported into the page. As DOM elements, they follow all the same rules and have access to the same APIs as all other page elements. Let’s take a quick look at each element comprising our smiley face:

 <circle cx="300" cy="164" r="160" fill="yellow" stroke="black"
stroke-width="2" />

This first element is the yellow circle that represents the head of the smiley face. As you can glean from the preceding code, the element is actually a circle element that has attributes representing the following:

cx, cy

These are the x and y positions of the circle as it relates to the SVG object in the page.

r

This is the radius of the circle represented in points (a numeric value).

fill

This refers to how the inside of the object is painted. An element can be filled with a color, a gradient, or a pattern (such as an imported image).

stroke

This represents the actual shape of the object or line (including the text). The stroke can be colored with the same options as the fill.

stroke-width

This is only necessary when you have a stroke declared. As is obvious in the attribute name, this declares the width of the stroke in points. The default is 1.

The next two elements are the eyes of the smiley face. They contain many of the same attributes as the previous circle. The two circles are identical to each other except for the x positions that draw them on different sides of the head.

  <circle cx="210" cy="100" r="20" fill="black" />

  <circle cx="380" cy="100" r="20" fill="black" />

The clip path may be an unexpected element for this illustration. Not to give away the ending, but the final element will be another circle that represents the smiling mouth in the illustration.

  <clipPath id="MyClip">
    <rect x="30" y="200" width="600" height="100" />
  </clipPath>

The clip path is a parent element to other SVG elements that have a clipping effect instead of a painting effect. The clip path has a single attribute:

id

The id looks a lot like a DOM id because it is a DOM id, and it’s necessary in this case for us to reference the clip path by another SVG element.

The clip path contains another element:

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

This is exactly what it looks like. You were already introduced to the circle element; well, this is a rectangle element. If the rect element wasn’t contained by a clip path, it would draw a 600 × 100 rectangle on the SVG object.

  <circle cx="300" cy="160" r="120" fill-opacity="0" stroke="black"
  stroke-width="5" clip-path="url(#MyClip)" />

This final object is the mouth. This circle has two new attributes that we want to look at:

fill-opacity

This is a value between 0 and 1 that declares how opaque our fill should be. Since we want the circle to appear empty, we have it set to 0.

clip-path

This references the DOM id for the clip path within our SGV file. When we reference the clip path, the shape gets applied to this element, in a manner that clips off anything (fill or stroke) within the image.

We could have drawn a line for the mouth of the smiley face, but it would have been a lot more work to draw out that shape in XML than it would be to just declare a whole circle, and then clip half of it off.

When we take all those SVG elements and wrap them in an <svg> tag, we can see how simple the code really is:

<svg version="1.1"
     baseProfile="full"
     xmlns="http://www.w3.org/2000/svg">
  <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)" />
</svg>

These 11 lines of code are all we need to draw out our friendly smiley face. The code is significantly lighter than a JPEG or even a GIF that would represent the same image. Additionally, you inherit all the benefits of first-class DOM objects, as we previously discussed.

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