Login | Register   
RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


Go Shopping with SVG: A Hands-on Graphics Tutorial : Page 4

Though it's often overlooked, SVG is poised to become the dominant graphics environment for the Web and desktop during the next few years. Learn the ins and outs of this up and coming technology with this virtual shopping mall application.

Building the Mall
SVG is an XML document, and as such, prior to establishing the document element of the SVG, you can specify a stylesheet. The Mall.svg (Listing 2) file does so declaring a (more or less) standard CSS stylesheet. Though these are principally used for defining CSS classes rather than setting individual element appearances directly:

<?xml-stylesheet type="text/css" href="mall.css"?>

This mall.css (Listing 3) file contains a series of class definitions, which in general look like the following:

.str0 {stroke:#1F1A17;stroke-width:28} .background {fill:url(#kioskBackground)} .mall {fill:url(#mallBackground);stroke:#1F1A17;stroke-width:28} .store {fill:url(#store);stroke:#1F1A17;stroke-width:28} .storeCategory {fill:url(#storeCategory);stroke:#1F1A17;stroke-width:28}

Note that you can reference certain paint servers, such as gradients, within a CSS style using the fill:url() notation and placing a reference to an external item.

The mall graphic itself contains a mix of explicitly stated content and content generated from Javascript (shown in Listing 4). The SVG document declares the two relevant SVG namespaces, the default SVG namespace and the XLink namespace used for linking internal content.

<svg xmlns="http://www.w3.org/2000/svg" xlink:xlink="http://www.w3.org/1999/xlink" width="11in" height="8.5in" viewBox="0 0 11000 8500" onload="retrieveData(evt)">

The <svg> element then specifies the width and height of the container and creates a ViewBox (a graphics context) with the origin at the upper left corner, and 1000 user units per inch of height. It's worth remembering here that the user coordinate system only provides an abstract coordinate layer—the SVG processor will map this abstract coordinate system into the physical pixel coordinates used by the operating system.

The SVG <defs> block is used to define static graphics primitives. Some of the more useful of these are custom gradients that can be used here to signify certain states for the stores and for the category buttons. The semantics of the gradients id make it possible to define "colors" that have specific relevance—such as the "store" and "storeHighlight" colors, defining the neutral and highlighted (rolled over) state of any store (or store-like region, such as a bathroom or information kiosk).

<defs> <linearGradient id="store" gradientTransform="rotate(45)"> <stop offset="0%" stop-color="blue"/> <stop offset="100%" stop-color="navy"/> </linearGradient> <radialGradient id="storeHighlight"> <stop offset="0%" stop-color="white"/> <stop offset="100%" stop-color="lightBlue"/> </radialGradient> <!-- more gradients --> <defs>

In addition to the gradients, the defs section also defines the standard "button" used for selecting a given category:

<g id="categoryTemplate" onclick="showStoresByCategory('template')"> <rect id="template_box" width="200" height="200" x="-220" class="categoryBox"/> <text id="template_text" class="legendText">template_label</text> </g>

The <g> element bundles both the rectangle and the associated text box together into a single unit, setting up a format in which the word "template" will get replaced with the appropriate category ID. For instance, the code for "restaurants" would use the template to generate a button which looks like this:

<g id="restaurants" onclick="showStoresByCategory('restaurants')"> <rect id="restaurants_box" width="200" height="200" x="-220" class="categoryBox"/> <text id="restaurants_text" class="legendText">Restaurants</text> </g>

The mall itself is outlined with a thicker border, and can be selected as a separate entity on a mouseover, which handles displaying "default" information using the displayInfo() function. This is defined later in the scripts.

<g id="MallOutline" onmouseover="displayInfo(evt)"> <rect id="background" class="background" x="0" y="500" width="13000" height="8000"/> <path id="outline" class="mall" _ d="M10972 6979l0 -2492 -4246 -13 0 -3547 -2386 0 0 3574 -4285 0 -14 2478 10931 0z"/> </g>

Each store's shape is defined using one or more graphical primitives (usually, but not always, paths), contained in a single <g> element that acts as the aggregator for events:

<g id="storeLayer" onmouseover="displayInfo(evt)" onmouseout="restore(evt)"_ onclick="showVideo(evt)" cursor="pointer"> <path id="store01" class="store" d="M3285 4517 l0 883 653 0 0 -883 -653 0z"/> <path id="store02" class="store" d="M2685 4880 l0 520 600 0 0 -883 -376 0 0 363 -224 0z"/> <path id="store03" class="store" d="M3938 4517 l0 883 652 0 0 -883 -652 0z"/> <path id="store04" class="store" d="M2210 5404 l475 -4 0 -520 224 0 0 -363 -699 0 0 887z"/>

Each store's id ties it to the XML document defined previously, while the class attribute applies the appropriate CSS class to each shape. Note that again the