SVG is a format for vector graphics. In raster graphics, the image is made of a large number of colored dots. Vector graphics, on the other hand, are made up of a series of graphic objects.
In a raster graphic, a blue circle is a bunch of blue dots that happen to be contiguous and roughly circle shaped. In a vector graphic, a blue circle consists of a circle object with a specific position, radius, and a color of blue.
One side effect of this approach is that vector graphics are effectively infinitely scalable.
W3C Recommendation since 2001
Although you may have only heard of SVG recently, it's actually been around for a long while. Several viewers have been in place for many years. We're currently on our 3rd revision of the standard (1.0, 1.1, and 1.2). The result is a relatively mature specification.
XML-based vector graphics format
As an XML-based format, SVG is extensible. It is not a binary format that is difficult to extend. SVG supports foreign namespaces. This allows you to embed non-graphic information that is easily parsed out of the file. (We'll have an example of this later.
This also means that creating SVG is something that you can do by hand, with an XML editing tool, or through code.
Most of all, SVG is a graphics format.
Support for declarative animation
SVG imports parts of the SMIL specification relating to animation. This allows you to specify in XML animation effects including movement and transformation of objects, changing attributes, and some user interaction.
Support for scripting
SVG supports the ECMAscript scripting language for programmable interaction. With scripting, you can interact with the DOM of the document, react to user events, make calls to external servers, etc. This feature supports building small applications in SVG.
Here in mid-2009, scripting seems to be implemented more widely than SMIL in the web space. I have the impression that it's the reverse in mobile devices.
A new programming language
SVG is not a replacement for all of the programming work you are doing on a given project.
A complete replacement for Flash
Many people remain focused on the idea of SVG as a Flash killer. And, to be honest, there are some areas where Flash and SVG can both be used. However, their approaches are quite different. So there are undoubtedly places where one is more effective than the other.
I don't know enough about Flash to give a good explanation of where it would be most effective.
A magic solution to all web image woes
Some people seem to want to use SVG to replace all images on their site. But, SVG is not a replacement for everything. PNG and JPEG still have their place. SVG is actually lousy for encoding photographs or photo-realistic images. These kinds of images are much more efficiently stored in raster formats.
A GUI design tool
I often see the complaint that SVG will never amount to anything because it doesn't have menus, radio buttons, checkboxes, and other GUI controls. Strangely, the same people don't claim that JPEG is dead for these same reasons.
SVG was intended, from the beginning, to be a technology that would work well with other XML-based specifications. There has been quite a bit of experimentation with using SVG and HTML together. The W3C is also currently working on better interaction between HTML and other forms of markup for HTML 5.
That said, SVG is well-suited to building graphic elements for GUIs. It is used relatively extensively in KDE. It is also supported by Opera widgets.
Completely supported everywhere
This is the biggest problem at the moment. SVG support is growing in all of the major browsers except one. There are a few plugins that add support to IE, with more on the way.
More importantly, browser support is increasing at a rapid pace. Three or four years ago, browser support was almost non-existent. Now large portions of the specification are supported by Firefox, Opera, Safari/Webkit, and Chrome.
It's my understanding that one of the biggest applications for SVG support has been mobile phones, mostly in Asia. We are seeing a small amount of that uptake trickling over to the west.
Infinitely scalable graphics
Okay, this is basically in the definition, but it's worth saying.
Art
SVG has been used quite a bit for clipart and icon development (KDE). But, I've also heard of some people doing more interesting artsy things with the technology. It's not my area, so I haven't looked into it very far.
Comics
Another area where I haven't spent much time. But, SVG seems to be a medium some have used for web comics. I should warn you that the Dragon Knights comic has some novel navigation effects and takes a bit of getting used to.
Games
Many people have coded games in SVG because it seems to be an obvious use for graphics and scripting in the same tool.
Maps
The cartography community has really embreaced SVG. They can not only generate extremely high-quality maps, but they can add interactivity and extended data to those maps. In some ways, these guys have been pushing the use of SVG more than almost anyone else.
Applications
(We'll have a few examples later.)
All of the games could be treated as applications. I know of one company that had an EMS (Energy Management System) with a Batik-based SVG front-end.
This is the part of SVG that really grabbed my attention. Building nice-looking
graphics from code is not generally easy. How many of you can create nice-looking
JPEGs, given only a JPEG library? How many of you have used
Image::Magick
? How easy is it?
About the only graphics most of us generate are relatively straight-forward line and bar graphs. Maybe a pie chart, here and there. For those, we would probably rely on a library that does the heavy lifting for us. It's not that general graphics are impossible to do from code. But, most formats are optimized for storage space and display speed, not ease of programming.
Web Browsers
You'll probably notice one browser conspicuously missing from this list. Although MS keeps saying they are looking into SVG, they don't seem to have made any progress with this open web standard. Of course, they have continued on their own proprietary technologies.
In fact, Tim Berners-Lee called them out on it in an MSNBC interview.
Browser Plugins
Adobe released ASV shortly after the first SVG specification was released. Around the same time-frame, Corel also introduced a plugin as well. Although not perfect, ASV was good enough that no one found a need to build a new one.
When Adobe and Macromedia merged, ASV became a bit of an orphan. Adobe has pledged to keep it available, but it is officially unsupported. Given the fact that Microsoft has not provided SVG support in IE, several other groups have stepped up to try to get an IE-compatible plugin for SVG display.
SVG-specific Viewers
The Batik library has an SVG viewer as an example application. Both KDE and GNOME provide support in the window manager for display of SVG.
Mobile devices
Japan has been pushing the state of the art in mobile devices. Asia has actually embraced SVG as a core technology for their mobile devices. Both Trolltech and Ikivo produce SVG libraries for mobile devices. The browser maker Opera also has a mobile edition. The iPhone runs a Webkit-based browser.
Development libraries
As graphics programmers have become more aware of SVG, general purpose graphics libraries sprout SVG support. There are also SVG-specific graphics libraries.
Since SVG is XML (basically text), you can generate SVG any way you can generate XML.
<rect x="10" y="10" height="50" width="100"
fill="green" stroke="none" />
Of course, to be XML it must be well-formed; and to be SVG, it must be valid. But other than that, there are a number of ways to generate it.
print
Method
print qq{<rect x="10" y="10" height="50" width="100"},
qq{ fill="green" stroke="none" />\n};
It's relatively easy, and requires no extra libraries. However, there's no support for making sure you are building well-formed SVG. There's no help for attribute and element names. There's no help for getting the namespaces correct.
You are basically on your own.
XML::LibXML
Method
my $rect = $doc->createElementNS( $svgns, 'rect' );
$rect->setAttribute( 'x', 10 );
$rect->setAttribute( 'y', 10 );
$rect->setAttribute( 'height', 50 );
$rect->setAttribute( 'width', 100 );
$rect->setAttribute( 'fill', 'green' );
$rect->setAttribute( 'stroke', 'none' );
Much more verbose than the print
approach. But, output is
guaranteed to be well-formed. There are no guarantees about valid SVG,
but at least the output is XML.
The verbosity issue can be handled with higher level subroutines.
SVG
Method
$svg->rect(
x=>10, y=>10, height=>50, width=>100,
fill=>'green', stroke=>'none'
);
Much less verbose than the XML::LibXML
approach. Slightly
more verbose than the print
approach. More protection against
invalid elements. No protection against invalid attributes.
Namespace declarations are taken care of so you don't have to.
In template
<rect x="[%x%]" y="[%y%]" height="[%height%]" width="[%width%]"
fill="[%color%]" stroke="none" />
In code
$tt->process( $fh,
{x=>10, y=>10, height=>50, width=>100, color=>'green'}
);
This approach is very useful if much of the SVG you need to output is boilerplate with a small amount that needs to change. Templates are a good way to separate the presentation part from the output you really need to create.
Thanks to its XML nature, every SVG file contains some boilerplate information. In addition, many SVG images contain a number of elements used for background imagery or supporting graphics. This boilerplate and static content can be placed in the template and does not need to be generated.
A lot of programmers decide to use SVG as an effective tool for generating graphs and charts. It appears that most of the SVG modules on CPAN are designed for graph generation.
Use a drawing package (like Inkscape) to build the background portions of the SVG and add to it with Perl.
An SVG application often consist of a small amount of boilerplate text, some background graphics, and some graphics that are generated by the code. The background stuff doesn't have to be static, it could be animated or support script-based interaction. The key part is that it does not need to change from one run of the program to the next.
Unfortunately, if the whole SVG application is generated with code, this boilerplate and background stuff needs to be written as well. But, some stuff is much easier to generate with a drawing program instead of with code. If the background portion can be read in and the result modified by code, you get the best of both worlds.
A template-based approach works particularly well with this idea.
Do: Rely on SMIL and scripting to animate on the client side.
Don't: Try to animate from the Perl side
If you aren't used to the scripting or animation capabilities of SVG, you might be tempted to Use a lot of request/response code to call to a Perl program to decide what to do next. This would not be the best approach.
For maximum responsiveness, you want to do work on the client side whenever possible. With SVG's scripting ability, you can do a surprising amount in the application. The games from the examples before give you a beginning idea of what is possible. If your viewer has SMIL support, you can get some animation and interactivity without any scripting at all.
Do: Use scripting to manipulate the DOM on the client side.
Don't: Try to push lots of rewrites from Perl.
If you need calculations or data that would be too much for the script to handle, you might want to make an asynchronous call to a server to retrieve just the data. Then, use scripting to manipulate the interface using the returned data.
Just like the whole AJAX thing, you don't need to send a whole new SVG file for an update. Maybe you can get away with sending the data that you can use to make the appropriate changes with scripting.
Do: Use scripting or SMIL on the client side to interact with the user.
Don't: Use request/response for user interactions.
In order for the application to have any reasonable responsiveness, you need to do as much interactive work as possible directly in the SVG. Users don't like waitign for request/response any more than is necessary.
Do: Use Perl to generate initial conditions.
Do: Pre-calculate tables of data to be used by the scripting.
Perl is a really effective general-purpose language. As powerful as ECMAscript has become, it still has limits because it is running in a sandbox in the viewer.
One thing that works extremely well is to take a trick from some compiled languages. In the Perl code, you can pre-calculate information that you output into the script as tables. This pre-calculation approach can result in the script being capable of more because the heavy lifting has already been done.
Focus on using the best tool for the job.
The key to good Perl/SVG applications is to use the each language in a way that plays to that language's strengths.
Game application written for my son.
This started as a simple application that took output from the Games::Maze
module and generated better looking graphs. From there, it evolved different styles and
sizes for more challenges. The interactive side came last as I realized that not much
was needed to make them actually playable.
Application for my wife's calligraphy hobby.
This was a quick-and-dirty implementation using the print
method.
It's main positive attribute is that it works.
Perl program for generating graphs using Template Toolkit from profiling data on different viewers.
This application was part of a profiling project I did for measuring the speed of scripting implementations across several viewers.
It was also the first time I had tried using Template Toolkit for generating non-trivial SVG.
Perl works as a server-side process to supply data to SVG-based virtual instruments.
This is a work in progress.
The application here is a prototype for the sole purpose of demoing the idea. One of these days, I need to get around to finishing it.
Perl module for creating sparklines.
The Perl code can support substantial configuration and build a small SVG file.
Because there can never be too many graph modules on CPAN, I wrote the SVG::Sparkline module. SVG makes sparklines easier than in most graphing libraries because of the scaling issue. However, general-purpose graphing libraries are too general to fit the intent of sparklines.
This library was also a mechanism for me to explore the SVG Perl module.
Batik is probably the most mature of the language libraries out there. It supports both generation and rendering of SVG. Current versions support much of the specification, with the nightly builds pushing the support even further.
There are a few libraries for generating SVG from Ruby. Of course, one of them is a DSL.
In typical Scheme fashion, we generate SVG from Lisp-y S-expressions, because parentheses are much more natural than angle brackets.<grin/>
These are good sources for the latest information on SVG.