Tips and Scripts
About the code samples.
This is a combination of a FAQ and a code snippet library. It will show hints on best-practice for authoring SVG documents, as well as answer some perennial questions that pop up in the SVG developer community.
Doing the Right Thing in SVG.
There are often many ways of doing the same thing in SVG. Usually, there is a best way to achieve any given effect under a particular set of circumstances.
|When I want to hide an element, what's the best attribute to use?||There are three ways to hide an element from rendering: 'opacity', 'visibility', and 'display'. In general, it's most efficient to set 'display' to 'none', but see the sample for details.||HideShow.svg|
|Can I include an audio file in SVG? How do I start and stop it?||Yes and no. Adobe has provided a proprietary extension to allow referencing an audio file in SVG since version 3 of their viewer. However, it has not been part of the official SVG Spec. There is a proposed 'audio' element in the SVG 1.2 Spec. I have included a sample here to show both syntaxes, the proposed new one and the Adobe-only one, in a 'switch' element. The first (and preferred) one uses the official syntax, and it will play in ASV6pr1; the second fallback one, if the first doesn't work, is Adobe's, and it will play in ASV3. Start the audio by mousing over the graphic, and stop it by mousing out.||audioSwitch.svg|
More to come...
Using imperative EcmaScript in SVG.
|How can I insert shapes into SVG using script?||You create a shape using 'createElementNS()', give it attributes using 'setAttributeNS()', and then append it to the appropriate node (such as the root) using 'appendChild()'. Here is a sample that will randomly generate a rectangle or a circle every few seconds (using the 'window.setTimeout()' method), assigning it unique styling attributes and locations, add appropriate 'title' and 'desc' elements, and then add append it to the document. Note that except for the root-level 'title', 'desc', and 'script' elements, this document is entirely blank when it loads; this is a basic example of a document created entirely from client-side script.||RandomShapes.svg|
|How can I add drag-and-drop to my SVG document?||I think that this should be a basic function of SVG (see my BAM proposal), but in the meantime, here's a simple prototype drag-and-drop example.||DragAndDrop.svg|
|How do I get the animated value of an element?||In Batik or ASV6pr1, you can use the 'animVal' and 'baseVal' properties. The sample file will show these values; if you click on the vertically-animated circle, the other circle will match its animated 'cy' value, and if you click on the horizontally-animated circle, the other circle will match its animated 'cx' value.||animVal.svg|
|How can I find the shortest path?||SVG has a method, 'getTotalLength()', that gives you the length of a path segment. This is very useful for mapping applications. PathLength.svg will show the shortest, longest, and median paths.||PathLength.svg|
|How can I pause SMIL animations, and resume them again at the same point?||While I believe there should be a way to do this declaratively, there is a way to do this in script, using the 'pauseAnimations()' and 'unpauseAnimations()' methods. This only works at the root document level, so it will pause all animations, even those not on a time (that is, event-triggered animations). You cannot currently pause single animations, though this functionality will be coming in SVG 1.2.||PausePlay.svg|
|I want to view a timed animation at a certain point in time. Is this possible?||Yes, for SMIL animations that are controlled by the global timer, you can set the current time of the document. This is useful for clock animations, for pausing between sessions (when combined with cookies to set the last time elapsed), or for scanning a time-dependent data visualization. As with 'pauseAnimations()' above, this only works at the root document level. This example shows a shape moving across the screen over the course of an hour, and by clicking on the timepoints, you can set the current elapsed time from second zero.||SetCurrentTime.svg|
|How do I show a tooltip in SVG?||In SVG 1.2, there is a proposed 'tooltip' attribute, which takes its content from the new 'hint' element. However, in the meantime, you can accomplish something similar manually in script, such as this sample, which shows the contents of the 'title' and 'desc' elements. The second example, Tooltip2.svg, shows a slightly more robust example, with options for no tooltip, or tooltip based on 'title' only, 'desc' only, or the 'id' attribute. See also trefMetadata.||
|I need to make sure that I'm using a certain version of the SVG viewer; how can I do that?||Adobe provides, from v3 on, a non-standard method for checking the viewer version, 'window.getSVGViewerVersion()'. The sample ViewerVersion.svg demonstrates this. That being said, it is rarely sound practice to check for a viewer version, since that limits your code's relevance to known features of current viewers. It is better to check for particular features and versions; a sample on how to do this is forthcoming. If using a declarative approach, you can use the 'switch' element.||ViewerVersion.svg|
|I have an image that needs to get more detailed as I zoom in. Can I do that in SVG?||Frequently, an author may wish to create an image that becomes more detailed as the resolution changes (as by a user-initiated zoom event). On a map, as you zoom in, a simple rectangle may resolve into a more complex shape of a block of buildings, or on a technical diagram, you may see more wires or components; having labels show up only at a certain level of zooming. This is typically referred to as LOD, or Level of Detail. The SVG1.2 Specification will introduce some functionality to achieve this, but in the meantime, one can achieve it in script. The sample simpleLOD.svg shows a simple city grid, where labels appear on the streets and buildings as you zoom in; this uses simple hiding and showing of text elements. A more complex use case may access the server to download additional or alternate content based on the user's current zoom level.||simpleLOD.svg|
More to come...
Using SVG's native declarative programming abilities.
SVG has very good support for declarative programming to accomplish animation and user interaction. Many times, it is better and easier to rely on SMIL animation to accomplish tasks than to script it yourself. Unlike imperative programming, declarative programming is based on setting up conditions and events for behaviors. Below are some explorations and examples of SMIL animation.
|How can I synchronize animations so that they happen in sequence?||You can always calculate the timing by adding the 'dur' from the reference animation to its 'begin' value, but a more efficient way is to use the 'end' event from one animation to trigger the 'begin' of another animation. The triggering animation can be referenced by the 'id', or if it is a sibling, by the 'prev' or 'next' keywords. You can even have an offset buffer time value, as in the last animation demonstrated in the sample file.||TheDominoEffect.svg|
|Can I move a shape along a path?||SVG has a specific syntax for animating an element along a path. The sample orbits.svg uses the the 'mpath' to move the planets along their elliptical paths (and also includes some script that tracks them with green connector lines), while autoOrient.svg describes the path in the 'animateMotion' itself, and also demonstrates the 'rotate' attribute.||
|Is it possible to display element metadata without using scripting?||Normally, such text-node data as is stored in non-rendering, semantically-tagged 'title', 'desc', and 'metadata' elements is not explicitly accessible except through DOM scripting or appropriate UAs (such as DOM-aware voice browsers). However, using the 'tspan' element, you can access the contents of any text node that has an 'id', even those of another document (if it's on the same server). Using the SMIL 'set' element, this sample changes the target of the 'tspan' to display the 'title' and 'desc' contents, when you 'mouseover' the parent element of those nodes; if you position your pointer in such a way that the spinning elements move under it, this will also trigger the event, which is rather interesting. Note that there is a proposed attribute in SVG 1.2, called 'tooltip', that instructs the UA to display (on mouseover, normally) the content of another proposed metadata element, called 'hint', which is intended to describe the manner in which a user can interact with the target element. See also tooltips.||trefMetadata.svg|
More to come...
All code linked from this page is licensed under a Creative Commons Attribution-ShareAlike 2.5 License.