Saturday, January 21, 2006

Combining AJAX, Canvas tag and SVG

Dave Hooper's recent article, All Aboard AJAX, HTML Canvas, and the Supertrain, on XML.com describes how to combine AJAX with the <canvas> tag. It is a very exciting article and trying out the example for yourself is a must. This is my first actual exposure to Ruby (I've known of it's existence for 5 years), now I just need to find out what all the fuss surrounding Ruby on Rails is about!

Dave also linked to another exciting example of the AJAX and <canvas> combination in his Lightweight Visual Thesaurus. Now if I were a Macromedia Flash devotee then I would probably find these developments slightly disturbing. However, surely a WYSIWYG editor for producing this kind of thing is a long way off, well perhaps it isn't that far off after all.

Firefox 1.5 included support for some shiny new features, okay I've gone on about E4X enough already but it also supports WHATWG's <canvas> tag (also used in Apple Safari) and has built-in support for SVG as a document format.

SVG and <canvas> both render graphics. I haven't looked at the Firefox source code but you would think that since SVG is rendered directly from an XML format file, I understand this is based on Cairo, and the <canvas> tag is JavaScript engine driven that their rendering mechanisms would actually have little in common. Indeed, if you look at <canvas> tag documentation and compare it directly to some examples of SVG they are quite dissimilar technologies. For example, how do you draw an elliptical arc using the <canvas> tag?

Well, programming with the <canvas> tag reminds me of the Logo programming language that they taught me at school but if I remember rightly when they showed me Logo at school they were trying to teach me mathematics! I'm far too lazy now a days as I'm used to drawing shapes in CorelDraw, PowerPoint etc. and not plotting co-ordinates by hand! I would expect that drawing any sort of complex graphic using the <canvas> tag would not be a painless experience. Granted SVG is a quite mathematical XML format but at least there are WYSIWYG graphics packages for producing SVG (Inkscape [open source vector graphics editor] looks particularly promising).

The future will include more about AJAX, <canvas> and SVG

Dave's article got me thinking that there must be some way of utilising SVG in JavaScript and perhaps using the <canvas> tag into the bargain. My first thought was to create an XSL stylesheet that could create <canvas> code from a SVG source but this seems like it would be a lot of work.

I then thought wouldn't it be great if I could load SVG files dynamically using AJAX and display them in my web pages. According to SVG in Firefox 1.5, Firefox handles SVG as entire documents or when referenced by embed/object/iframe. It cannot currently be used as source for a html/xhtml img element or for CSS properties that take an image reference.

However, I then found Antoine Quint's CanvaSVG which is described as a static SVG Tiny 1.2 implementation using the <canvas> APIs. Wow, a way to convert SVG format files into <canvas> examples and although not supporting the full SVG file format there are some very impressive examples (Tiger, Lion).

Great stuff, I just need to tweak it slightly to produce standards compliant XHTML and load the SVG from an external file using the XMLHttpRequest and I have the beginning of SVG file loading implemented using AJAX.

Click on the following images to see live examples of using CanvaSVG to load external SVG Tiny files using AJAX technology (requires Firefox 1.5).

Whilst messing with this example I noticed something a little strange. XUL programmers are probably way ahead of me on this one but I noticed that SVG seems to be a special format to Firefox 1.5. For example, using XMLHttpRequest req.responseXML.documentElement actually returns an SVGSVGElement javascript object rather than a straight forward XML Element object that I was expecting. However the full significance of this is actually unclear to me but I'm sure it is an area worthy of further exploration.

I think this technique has a lot of potential especially if you have a ready source of SVG Tiny documents to hand (For example, I believe GeoServer can produce SVG output). Combine this with other web services (Google Maps API, Yahoo web services etc) and who knows what mashup miracles you could come up with!

12 comments:

Mark McLaren said...

Mark,

I invite you to learn some more about SVG. The DOM elements you mention are not a "special format to Firefox". In fact IE + Adobe SVG Viewer and Opera 9 TP1 have the same DOM elements available to them. SVG 1.1 carries its own DOM which includes interfaces like SVGSVGElement (for the root svg XML element), SVGRectElement (for the rectangle XML element), etc. SVG is also fully scriptable, interactive and animatable.

In fact, Antoine created the CanvaSVG to prove to Safari developers that an SVG Tiny 1.2 implementation is not much more complex than an HTML canvas implementation.

Anyway, I have several SVG demos at my blog. I'd appreciate your valuable feedback.


Note: Comment imported. Original by Jeff Schiller website: http://blog.codedread.com/ at 2006-01-21 16:47

Mark McLaren said...

Hi Mark,





If you want to mix SVG and an AJAX architecture, you don't have to use <canvas>. For instance, if you're loading an external SVG file, you can just do the following:





var svg_result = req.responseXML.documentElement;

var doc_root = document.documentElement;

doc_root.appendChild(svg_result);





Actually, this is a little convoluted, as if you want to display some SVG file from the network, you can just generate an <object> element pointing to the SVG file that you want to display (static or dynamically-generated).





Now, in a typical AJAX setup, the data you'd receive through XMLHttpRequest would be some rax XML that you'd need to transform to some rendering. You can then just use regular DOM calls to create SVG elements on the fly. For instance, the following code will create a blue 100x100 rectangle located at [10,10]:





var svg_ns = 'http://www.w3.org/2000/svg';

var rect = document.createElementNS(svg_ns, 'rect');

rect.setAttributeNS(null, 'x', 10);

rect.setAttributeNS(null, 'y', 10);

rect.setAttributeNS(null, 'width', 100);

rect.setAttributeNS(null, 'height', 100);





The "rect" we have just created here can then just be appended to the DOM tree using appendChild(). Since SVG uses DOM interfaces to be programmed, just like (X)HTML, SVG can be used just like (X)HTML with an AJAX-like architecture.





Regards from France!


Note: Comment imported. Original by Antoine Quint website: http://fuchsia-design.com/ at 2006-01-21 20:33

Mark McLaren said...

Hi Jeff and Antoine,



Thanks very much for your feedback. Antoine, if I understand your first example, you're saying something like this will work.



















//Note: Comment imported. Original by markmc website: http://cse-mjmcl.cse.bris.ac.uk/blog at 2006-01-21 22:38

Mark McLaren said...

In Firefox you can actually embed SVG documents right inline with the XHTML code. For instance:





<?xml ... ?>

<html ... xmlns:svg="....">

<body>

<p>Blah blbah blah</p>

<svg:svg ...>

<svg:circle .../>

</svg:svg>

<p>Foo bar foo bar</p>

</body>

</html>





Note that it's not as easy to do this in other browsers (such as IE with the Adobe plugin), since IE doesn't support XHTML yet (maybe IE8?). So for now it may be easier to embed SVG by reference using the html:object tag (like your example).



And yes, you can include JavaScript right into SVG files (using the element, very similar to the html:script element), so Ajax is entirely possible using standard means like XMLHTTP (Adobe has similar proprietary functions that you can use as well, getUrl() I think).



Regards,

Jeff
Note: Comment imported. Original by Jeff Schiller website: http://blog.codedread.com/ at 2006-01-22 02:47

Mark McLaren said...

You can just append SVG elements into XHTML in Firefox 1.5 (or Opera 9, or latest development builds of Safari). Try this for instance:











SVG in XHTML test









Note: Comment imported. Original by Antoine Quint website: http://fuchsia-design.com/ at 2006-01-22 09:22

Mark McLaren said...

That is great, thanks guys.



To summarise (for personal future reference) these are examples of some of the SVG techniques that you have described :





SVG loaded via the <object> tag

SVG loaded AJAX style using XMLHttpRequest and added into the page

SVG elements can be written directly into the page (browser support permitting)





Additionally, I can also use XMLHttpRequest directly inside a SVG file.





Brilliant!


Note: Comment imported. Original by markmc website: http://cse-mjmcl.cse.bris.ac.uk/blog at 2006-01-22 11:09

Mark McLaren said...

Examples all work in Firefox 1.5. Bonus points if you can get your second example working in Opera 9 TP1...
Note: Comment imported. Original by Jeff Schiller website: http://blog.codedread.com/ at 2006-01-23 13:17

Mark McLaren said...

Always up for a challenge Jeff!



SVG loaded AJAX style using XMLHttpRequest and added into the page [Opera 9TP1 version]





I eventually managed to coble something together that works in Opera 9 TP1 (and it still works in Firefox 1.5) but Opera is surely broken. I can see how Opera might be interpreting the DOM importNode spec more correctly than FF1.5 but you would think that would be sufficient to get it working. I can only guess that Opera isn't implementing the "deep" import properly.


Note: Comment imported. Original by markmc website: http://cse-mjmcl.cse.bris.ac.uk/blog at 2006-01-23 21:37

Mark McLaren said...

Excellent work on this. Can you please either open a bug against Opera 9 or contact one of their developers (sometimes through the support forums)?



With your help, it might be possible to fix this before Opera 9 is officially released.
Note: Comment imported. Original by Jeff Schiller website: http://blog.codedread.com/ at 2006-01-25 04:17

Mark McLaren said...

Absolutely clear and straight forward I would like to thank you at explaining this to us.



http://googleblogg3r.blogspot.com
Note: Comment imported. Original by Google Blogspot website: http://googleblogg3r.blogspot.com at 2006-03-25 06:33

Mark McLaren said...

Another application of AJAX + CANVAS: http://ueluei.googlepages.com/pixvolution.html
Note: Comment imported. Original by Anonymous at 2006-04-22 13:58

Mark McLaren said...

Check out this AJAX design collaboration tool that uses Canvas and SVG for its vector drawing. Having implemented it, I can state with confidence that both technologies are severely lacking. It's a sad state of affairs, and it doesn't look like we're going to see any improvements for a long time.


Note: Comment imported. Original by Jason Kester website: http://www.twiddla.com/ at 2007-09-05 18:07