Embedded SVG
August 30th, 2006http://pwdemo.rcode.net/svg_tester
![]()
I know I’m probably late to the game on this one, but I had not realized until recently how well SVG was supported in a lot of browsers. I actually didn’t realize it until I needed it for a visually rich application prototype I’m working on. I really didn’t want to use Flash, so I checked out SVG again. To my suprise, it is fully integrated into Firefox, Opera 9 and some (pre-release?) versions of Safari.
So I started with the SVG example from Mozilla.org. It draws three circles with primary colors that are semi-transparent:
1: <svg xmlns="http://www.w3.org/2000/svg"
2: version="1.1" width="500" height="500"
3: baseProfile="full">
4: <g fill-opacity="0.7" stroke="black" stroke-width="0.1cm">
5: <circle cx="6cm" cy="2cm" r="100" fill="red"
6: transform="translate(0,50)" />
7: <circle cx="6cm" cy="2cm" r="100" fill="blue"
8: transform="translate(70,150)" />
9:
10: <circle cx="6cm" cy="2cm" r="100" fill="green"
11: transform="translate(-70,150)" />
12:
13: </g>
14:
15: </svg>
16:
I thought a modest goal would be to adapt Protowidget so that it could attach widgets to some SVG elements. I could then use the property bindings to make the circles move around. It’s dumb and pretty simple but forms the basis for creating more advanced SVG widgets.
This turned out to be harder than I had expected. The main culprit was that Protowidget wasn’t fully compatible with real XHTML. There’s the normal stuff: no document.write (it was used to bootstrap the system by writing script elements to the header), createElement must use namespaces, etc. It took a little longer than necessary to fix because I still wanted to preserve compatibility with namespaced xml documents and IE when the advanced features were not in use.
So I fixed all of that and added real namespace support so that the Protowidget attributes are now part of their own namespace if using an XHTML document. If working in normal HTML, the pw.* syntax can still be used. There’s even a hack, so that if you use the “pw:” prefix for your namespace, the parser will be able to work around IE’s deficiencies. I then added an SvgWidget to mirror the HTML DOMWidget (which in hindsight should have been named HTMLWidget). It’s basically a light version of the DOMWidget base class which leaves off the CSS class and style processing that does not apply (at least in the same way) to SVG elements.
The end result was to change the example SVG to include some Protowidget attributes:
1: <svg xmlns="http://www.w3.org/2000/svg"
2: version="1.1" width="500" height="500"
3: baseProfile="full">
4: <g fill-opacity="0.7" stroke="black" stroke-width="0.1cm">
5: <circle cx="6cm" cy="2cm" r="100" fill="red"
6: transform="translate(0,50)"
7: pw:type=’Svg.SvgWidget’
8: pw:element.r=’#{`Jitter1`}’/>
9: <circle cx="6cm" cy="2cm" r="100" fill="blue"
10: transform="translate(70,150)"
11: pw:type=’Svg.SvgWidget’
12: pw:element.r=’#{`Jitter2`}’/>
13: <circle cx="6cm" cy="2cm" r="100" fill="green"
14: transform="translate(-70,150)"
15: pw:type=’Svg.SvgWidget’
16: pw:element.r=’#{`Jitter3`}’/>
17: </g>
18: </svg>
19:
What this does is declare the three circle elements to be of Protowidget type “Svg.SvgWidget”. As I mentioned before, this is intended to be a base class for more advanced Svg widgets, but it provides some features that make it useful on its own. For one you can establish bindings between Protowidget models and attributes of the elements. This is what is done with the pw:element.r attributes. They are binding the circle’s radius to the values of “Jitter1″, “Jitter2″ and “Jitter3″ respectively.
What makes this go is a little chunk of code in the header that sets up a timer to set Jitter1, Jitter2 and Jitter3 to random values:
1: PwLoader.inlineExecute(function() {
2: Protowidget.beforeStartup(updateJitter);
3: });
4:
5: function updateJitter() {
6: Protowidget.RootWidget.setAttribute(’Jitter1′, 100+Math.random() * 50);
7: Protowidget.RootWidget.setAttribute(’Jitter2′, 100+Math.random() * 50);
8: Protowidget.RootWidget.setAttribute(’Jitter3′, 100+Math.random() * 50);
9: setTimeout(updateJitter, 100);
10: }
11:
(The couple of lines at the top are necessary for inline scripts that act outside of the module system. It ensures that the script is executed at the proper time in the startup sequence.)
Pretty neat, huh!
Here’s the URL again: http://pwdemo.rcode.net/svg_tester
I’ve tested it with Firefox 1.5 and Opera 9. It should work on Mozilla builds with SVG enabled.
For anyone whose interested, you can get all of this from anonymous svn: https://dev.rcode.net/svn/protowidget/trunk/protowidget
You can also visit the Protowidget Wiki.
13 Responses to “Embedded SVG”
Leave a Reply
You must be logged in to post a comment.
August 31st, 2006 at 7:46 am
[…] Terrt Laurenzo has posted on Embedded SVG from his experience starting with the SVG example from Mozilla, and adapting Protowidget so that it could attach widgets to some SVG elements. PLAIN TEXT XML: […]
August 31st, 2006 at 9:23 am
Just to let you know your example doesnt work in the Safari WebKit nightly
August 31st, 2006 at 9:47 am
Thanks Geoff. I figured that might be the case. Unfortunately I’m a little crippled on the Mac front now and can’t get access to the latest WebKit nightlies. I’ve finally got a Mac here but its waiting on an up-to-date OS.
August 31st, 2006 at 8:25 pm
This works on the WebKit nightlies now. The non-SVG stuff works on Safari 2 as well, but for some reason the non-SVG demos are not working on the nightlies. Weird! I’m done for the night, though.
September 1st, 2006 at 6:09 am
I’ve been tweaking with SVG behaviour and I am slowly approaching IE support. Look at these two examples. They are identical, only one has .xhtml and the other .html file extension.
.html - works fine in IE
.xhtml - works fine in Mozilla/Opera (I have no means to check in Safari)
http://sweb.cz/nxtwrld/ultimatesvg.html
http://sweb.cz/nxtwrld/ultimatesvg.xhtml
I can’t seem to overcome this issue and make it truly crossbrowser ;(
September 1st, 2006 at 7:29 am
nxt, I have been curious about how to get SVG working in IE. I knew the Adobe plugin was involved but had not gotten any further than that.
Do you know how well the DOM access works going from the HTML JScript side into the Adobe SVG side? My stuff is pretty heavy DOM manipulators and a seamless interface is a must.
September 1st, 2006 at 7:38 am
It works just fine. There’s one problem though - the SVG namespace. If You notice, it’s not just …svg content , But every SVG tag is declared by a namespace … (it’s how IE identifies the content with the plugin). So the only thing is, that You can’t really use things like getElementsByTagName() and must replace them with the getElementsByTagNameNS() - where You can specify the namespace.
Otherwise it’s a DOM node like any other
September 1st, 2006 at 9:23 am
nxt, that’s pretty awesome and thanks for sharing!
Protowidget processes every DOM node so it should pick it up just fine without using getElementsByTagName and friends. The namespace thing is a little screwy, but you could probably get the same version by using xmlns:svg=”…” instead of using the default xmlns=”…”. At least then it is valid SVG/XML and valid for the Adobe plugin if you stick with the convention.
Another question: Do the styles always have to be included in the svg:svg element or is there some way to link them in for an entire document? It’s ok to include them inline for one SVG widget, but if defining a bunch of SVGs in a document, it will be unwieldy.
September 14th, 2006 at 2:15 am
As you’re new to the game, let this broad spectrum of links on SVG inspire you: http://svg.startpagina.nl
September 18th, 2007 at 7:03 am
Nice, thanks for sharing.