SVG: Evolution, Not Revolution
Introducing The New Web
This series of articles explores how to integrate SVG into your web applications. While building entire web applications in SVG+JavaScript is possible, most developers have spent a great deal of time and effort in HTML, JavaScript, CSS, and the DOM. Exploring some of the ways in which SVG can be used to integrate with and enhance HTML applications provides us an opportunity to apply what we've learned in SVG without having to start "from scratch" in developing web applications.
SVG, like XHTML, is a declarative XML grammar. XHTML is a format for text documents; SVG is a format for scalable web graphics. Also like XHTML, SVG comes with the ability to be scripted and provides its own Document Object Model (DOM).
Our Sample HTML Application
Let's start with a simple web application: A photo gallery. This application is bare bones, but for roughly 40 lines of code it's not bad: We've provided some minimal styling with CSS and 12 lines of JavaScript to handle switching images.
function showPreview(img) {
var div = document.getElementById("preview");
if(div) {
var preview_img = document.createElement("img");
preview_img.className = "the_preview";
preview_img.src = img.id + ".jpg";
while(div.hasChildNodes()) { div.removeChild(div.firstChild); }
div.appendChild(preview_img);
}
}
An equivalent web application could be built without any JavaScript by moving the business logic of the application to the server and employing a language such as PHP. For the sake of simplicity, the examples included in these articles will focus only on client-side interaction and use JavaScript.
Our first step will be to build the same functional application using SVG for the graphical elements. In other words our HTML document will host SVG thumbnails and an SVG preview image. In the process we will learn a little about the capabilities of SVG, how to integrate SVG with HTML, and how to script across the HTML-SVG document boundary.
A Quick Introduction To SVG
The SVG language supports three types of graphical objects:
- Vector shapes (circles, rectangles, paths)
- text, and
- raster graphics
These types of objects can be styled, transformed, decorated, animated and made interactive in various ways. Here is a simple SVG document that displays a circle and a rectangle:
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> <circle cx="100" cy="100" r="30" fill="blue" stroke="red"/> <rect x="10" y="10" width="80" height="40" fill="yellow" stroke="black"/> </svg>
SVG provides many different general-purpose shapes: circle, ellipse, rectangle, line, polyline, polygon, and path elements.
Here is a simple SVG document that displays a raster graphic with the circle and rectangle drawn overtop:
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <image xlink:href="calif3-thumb.jpg" x="20" y="20" width="100" height="75" /> <circle cx="100" cy="100" r="30" fill="blue" stroke="red"/> <rect x="10" y="10" width="80" height="40" fill="yellow" stroke="black"/> </svg>
The SVG image
element is the equivalent of the HTML img
element and simply displays a raster graphic in a viewport.
For those new to SVG documents in general, here are a couple important points to keep in mind:
- It is important to include proper XML namespace declarations in the root
svg
element as we've done above, since SVG uses attributes from different namespaces - SVG elements can be styled using CSS just like HTML. You can either specify "style" attributes on elements, include
style
elements that describe the CSS rules, or reference external stylesheets using a mechanism similar to the HTMLlink
element. - SVG documents have a Document Object Model (DOM). This means that, like HTML, each SVG tag corresponds to a DOM node that implements one or more interfaces. For example, the SVG
image
element results in a DOM node that implements the SVGImageElement interface. - SVG documents can be scripted. Just like HTML, the SVG
script
element allows you to define script processing instructions in JavaScript that operate on the DOM nodes in the document.
Integrating SVG with HTML
With this knowledge of SVG under our belts, how do we integrate such documents into the HTML "host" document? There are numerous ways of doing this: You can use HTML iframe
, you can include SVG code inline with XHTML (properly namespaced of course), but currently the most broadly supported and useful technique is to include the SVG document in an HTML object
element. The reason HTML object
is so useful is because it allows the author to specify fall-back HTML content that will be rendered in browsers that do not support SVG content. Here is a simple example:
<html> <body> <object type="image/svg+xml" data="foo.svg"> <!-- fall-back HTML content goes here --> <p>Sorry! Your browser does not support SVG! Please use a modern browser.</p> </object> </body> </html>
If you are able, turn your browser's SVG-rendering capabilities off (in Firefox, go to about:config and double-click svg.enabled) and then refresh the above example to see the behavior.
You can put any HTML content inside the object
as your fallback content. For example, a link to download a SVG plugin or install a SVG-enabled browser. For our SVG Photo Gallery, we will tell the browser to "fall back" to render the Example 1 HTML-only code. In other words, our fall-back content will be an HTML img
element.
Break On Through To The Other Side
Embedding SVG documents in HTML documents is useful, but where things become really interesting is being able to script between the documents. Remember, SVG documents are scriptable and have their own DOM. This means it is possible to affect the SVG documents from the HTML document and vice versa:
- Scripting from HTML to SVG: The contentDocument property of the HTMLObjectElement interface is the SVG document (i.e. the SVGDocument interface).
- Scripting from SVG to HTML: The frameElement property of the Window interface within the SVG DOM is the HTML
object
element. Note that this property only has a value if the SVG is embedded. If the SVG document is being viewed alone (non-embedded), the frameElement property is null.
Figure 1 - HTML-to-SVG Interface
Figure 1 shows how navigation between all elements (window, documents, objects, etc) is achieved in the DOM. The HTML document (the top-left block) has embedded an SVG document (represented by the bottom-right block) by using the HTML object
element. The HTML object's contentDocument property points to the document in the SVG DOM. Similarly, you can follow how other attributes and objects give the author links to other pieces within the DOM.
Photo Gallery in SVG
So here is the photo gallery application with all images replaced by SVG documents embedded via object
elements. Clicking a thumbnail image invokes a function on the host document which, in turn, calls a function on the preview image. The HTML document is serving as a "mediator" between the SVG thumbnail and the SVG preview document, routing script function calls appropriately. See Figure 2.
Some More SVG Details
Looking at the SVG thumbnail code:
<svg version="1.1" ...> <g id="thumbnail" cursor="pointer" onclick="if(gHtmlWin) {gHtmlWin.thumbnailClicked(gImgFilename); return false;}" > <rect id="blueborder" x="0" y="0" width="104" height="79" fill="blue"/> <image id="theThumbImage" class="thumb" x="2" y="2" width="100" height="75"/> </g> </svg>
SVG uses the SVG g
element to group logically related graphical elements. This is similar in concept to the HTML div
element, allowing you to treat the group of elements as one in terms of styling, behavior, transformation, etc. Thus, the graphical elements rect
and image
are placed into a graphical group identified as "thumbnail".
Also notice that in order to achieve the blue border from the HTML application, we place a SVG rect
element filled with blue underneath the raster graphic. SVG follows a "painter's model" in which elements are conceptually rendered in the order in which they are placed in the document. Since the blue rectangle exists earlier in the document and is slightly larger than the raster graphic, we see a thin border around the raster.
Notice that the graphical group that represents the thumbnail image has a cursor attribute which allows you to control what mouse cursor should be displayed when the pointer is over the element. The thumbnail also has an onclick handler which invokes the thumbnailClicked()
function in the XHTML document.
Conclusion, first part
We've given a brief introduction to SVG, how to integrate SVG into existing HTML applications and how to script between the documents. We used SVG to achieve parity with our HTML application and set the stage for future exploration. In the next article we will be exploring ways that SVG can actually enhance applications by providing useful client-side functionality. This will start to answer the question of why we have bothered to integrate SVG in the first place.
This article is licensed under a Creative Commons Attribution, Non Commercial - Share Alike 2.5 license.
Comments
The forum archive of this article is still available on My Opera.