This is a complete SVG file. You can copy it and use it as a starting point for your UI.
SVG 1.1
<?xml version="1.0"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid" > <script type="text/ecmascript"> <![CDATA[ // ...here is some ECMAScript, or at least an ECMAScript comment. // ]]> </script> <defs> <style type="text/css"> <![CDATA[ text { text-anchor: middle; } ]]> </style> </defs> <circle cx="50" cy="50" r="40" /> </svg>
SVG 1.2
<?xml version="1.0"?> <svg xmlns="http://www.w3.org/2000/svg" version="1.2" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid" > <script type="text/ecmascript"> <![CDATA[ // ...here is some ECMAScript, or at least an ECMAScript comment. // ]]> </script> <defs> <style type="text/css"> <![CDATA[ text { text-anchor: middle; } ]]> </style> </defs> <circle cx="50" cy="50" r="40" /> </svg>
This contains a <script> segment (which contains only a comment); a <defs> segment (which contains only a simple CSS stylesheet); and then one element to display, a <circle>.
Note that the SVG 1.1 file has a DOCTYPE
header, but the SVG 1.2 file does not.
Another note: In SVG 1.2, the type for
An SVG document is drawn "back to front". Shapes defined later are drawn on top of shapes defined earlier.
If you want to define a bunch of shapes as a "layer" (in the Photoshop sense), place them all into a group (a
SVG has a standard idiom for defining some shape and then "stamping" it multiple times into your document. You create the object inside your
It doesn't have to be a group; it can be any SVG element. Be sure to give it a unique
Then you can use it from the main part of your document:
The
For some SVG elements, setting "x" and "y" attributes has exactly the same effect as setting a "transform" attribute with a translation. For example, these two elements produce the same results:
However, this is not true of
...is not the same as this:
The latter does not produce an error, but the x/y attributes are ignored. If you want to change the position of a group, you must use a "transform" attribute.
This is legal, but the results will usually not be what you wanted. Imagine: you have defined some object, and you want it at a particular location.
Then you decide it's too big, so you scale it down by half:
That half-size all right, but it's in the wrong place -- it's at (25, 25) instead of (50, 50). The transform is scaling the position as well as the size.
There are a couple of ways to get around this. One, of course, would be:
...but that's confusing, and it will break again if you change your mind about the scale.
A clearer form is this:
Instead of "x" and "y" attributes, you add a translation (slide motion) to the "transform" attribute. Since the translate is given before the scale, the translate values are understood to be in pre-scaling units.
You could also put the translation on a separate group, encapsulating the original object:
It is possible to add text labels to any SVG element. These labels will appear if the player hovers his mouse pointer over the element.
The primary label is given by a
A more descriptive label should be put in a
It is legal to have both:
Note that mouse hovering is considered to be a pointer event. If you have set
By default,
There's nothing wrong with selectable text, but for most game UI elements, it's distracting. (Particularly labelled buttons -- you want an "Okay" button to be pushable, not selectable.) So you will generally want to turn this off. Conveniently (or not), there are several ways to do this.
The easiest method is to put a
It's a nuisance to apply such an attribute to every single
This applies to all
A third option is to set the attribute on a top-level group, and let all of your elements inherit it:
(It's even legal to set the same attribute on your top-level
However, if you do this, you'll be turning off pointer events for all your elements, not just text. All your buttons and so on will stop working. To counter this, you'll have to turn pointer events back on for those elements which should have them.
(This is not necessarily a bad strategy. You'll often have a lot of fiddly SVG objects, even in your buttons and clickable pieces. It saves time and complexity if just one element in each button -- the border shape -- is sensitive to pointer events. By turning them off in a top-level group, and then back on for specific elements, you can achieve this level of control.)
The valid
<script>
elements is supposed to be "batik.html" class=wikipagelink>Batik does not yet support this. (See [Batik bug 35549].)
Deciding what is displayed on top
<g>
tag). An SVG group acts as a layer; again, it is drawn back to front.
Make multiple copies of a template object
<defs>
block; shapes defined here are not displayed, only stored for later use.
<defs>
<g id="template">
<rect x="-20" y="-20" width="40" height="40"
fill="red" />
<circle cx="0" cy="0" r="23"
fill="green" />
</g>
</defs>
id
attribute. It is also a good idea to draw this object at the origin (position 0,0). The example above is centered at the origin.
<use xlink:href="#template" x="50" y="50" />
href
attribute refers to the id
of the template object.
Don't use x/y attributes on a group
<use xlink:href="#template"
x="50" y="50" />
<use xlink:href="#template"
transform="translate(50,50)" />
<g>
(group) elements. This:
<g transform="translate(50,50)">
<circle cx="0" cy="0" r="23" fill="green" />
</g>
<!-- wrong -->
<g x="50" y="50">
<circle cx="0" cy="0" r="23" fill="green" />
</g>
Don't use x/y attributes and transform on the same object
<use xlink:href="#template" x="50" y="50" />
<!-- wrong -->
<use xlink:href="#template" x="50" y="50"
transform="scale(0.5)" />
<use xlink:href="#template" x="100" y="100"
transform="scale(0.5)" />
<use xlink:href="#template"
transform="translate(50,50) scale(0.5)" />
<g transform="translate(50,50)">
<use xlink:href="#template"
transform="scale(0.5)" />
</g>
Add tooltips to SVG elements
<title>
child element:
<circle cx="30" cy="30" r="10">
<title>Round button</title>
</circle>
<desc>
child element:
<circle cx="30" cy="30" r="10">
<desc>This makes the game go.</desc>
</circle>
<circle cx="30" cy="30" r="10">
<title>Round button</title>
<desc>This makes the game go.</desc>
</circle>
pointer-events="none"
on an element (see below), tooltips will not appear.
Make text unselectable
<text>
elements in an SVG file are selectable. The player's cursor will turn into a text bar over these elements; he can click-and-drag to select a range of the text, or double-click to select the whole thing.
pointer-events="none"
attribute onto each <text>
element. This makes your text impervious to mouse action.
<text
pointer-events="none"
x="10" y="10">
Hello
</text>
<text>
element, so you may instead want to use a stylesheet:
<defs>
<style type="text/css">
<![CDATA[
text {
pointer-events: none;
}
]]>
</style>
</defs>
<text>
in your document.
<g pointer-events="none">
<text x="10" y="10">
Hello
</text>
</g>
<svg>
element, which everything inherits from.)
<g pointer-events="none">
<text x="10" y="10">
Hello
</text>
<circle cx="30" cy="30" r="10"
pointer-events="all"
onclick="handle_click()" />
</g>
pointer-events
values are described in the [SVG spec]. Most often you'll want to use none
(no clicks), all
(accept clicks inside the shape or on the border stroke), or visible
(same as all
when the object is visibility="visible"
, but none
when it's visibility="hidden"
).
See also