The ability to create rich graphics on the fly is one of the critical gaps in Ajax. There are indeed techniques to do it, albeit far from perfect, and some are do-able today if you take a pragmatic view of things and keep graceful degradation in mind.
Here I list all the techniques I can think of to create graphics and images dynamically when you’re creating an Ajax/DHTML/Javascript web app, with varying degrees of portability and usability. Starting with the obvious and ending with the obscure. Please submit any other techniques you’re aware of!!!
- Use SVG. Current versions of Firefox, Opera, and Safari (nightly builds) support SVG natively, but with IE and older versions, users need to install a plugin. SVG is an old W3C standard that creates images based on XML. Being a vector format, it stores the image at a high level (curves, lines, etc), so it scales better than a plain bitmap. Here’s an SVG circle (adapted from W3CSchools:
- <svg width="100%" height="100%" version="1.1"
- xmlns="http://www.w3.org/2000/svg">
- <circle cx="25" cy="25" r="30" stroke="black"
- stroke-width="2" fill="green"/>
- </svg>
You could build up the XML string in the code or pull it down from the server with a remote request. However, you don’t actually have to specify the XML as a literal string message; you can create a blank SVG document object model (DOM) and manipulate it to build up an image. In this example, we create a circle of radius 25 (adapted from this tutorial):
- var svgDocument = evt.target.ownerDocument;
- var shape = svgDocument.createElementNS(svgns, "circle");
- shape.setAttributeNS(null, "cx", 25);
- shape.setAttributeNS(null, "cy", 25);
- shape.setAttributeNS(null, "r", 20);
- shape.setAttributeNS(null, "fill", "green");
-
Use Canvas. Canvas was introduced in Safari and now in Firefox and Opera too. No sign of life in IE, but this there’s a fantastic adaptor hack (via Ajaxian) that emulates Canvas using IE’s native VML support (more on VML below), and it’s now been rolled into an open-source project, ExplorerCanvas by some Googlers.
Where SVG is about things, Canvas is about actions. SVG documents represent images. Canvas tags include code to build up an image, a bit like moving a turtle in the Logo language. So you set a colour, draw something, change the fill style, draw something else, etc. You manipulate a Canvas tag like this:
- var canvas = document.getElementById('tutorial');
- if (canvas.getContext){
- var ctx = canvas.getContext('2d');
- ctx.fillRect(25,25,100,100);
- ctx.clearRect(45,45,60,60);
- ctx.strokeRect(50,50,50,50);
- }
(BTW Canvas uses the dreaded term, “Context”, to refer to what should really be called “paintbrush”, “pen”, or “turtle” … more concrete terms than “Context” which imply some sort of metaphor. But wouldn’t an imperfect metaphor be easier to grok than the generic “Context”? Alas, it’s a common idiom in graphics programming and will be around for a while.)
- Load dynamic images from the server. Once you have an image tag (either in the initial HTML or created on the fly with document.createElement(“img”), you can set its source to any URL, even external to your domain (though cross-domain “hot-linking” should generally be done only with permission). This is standard DHTML/Ajax stuff and works with any browser.
- button = document.createElement("img");
- button.src = "http://example.com/livechart.gif?interval=15"
-
Use Vector Markup Language (VML). VML is effectively the MS equivalent of SVG, and as such works in IE, and only in IE. As with SVG, you use XML to specify an image.
- <v:oval style="position:absolute; left:0; top:0;
- width:100pt; height:50pt"
- fillcolor="red">
- </v:oval>
- Introduce a Richer Plugin, most likely Flash, to beef up the browser’s multimedia capabilities.
- Rely on plain old CSS and the DOM. You can do some impressive-looking things with just CSS and the DOM, e.g. the CSS graphs library. And of course it’s easy enough to make it fully portable too.
- Create an image and set its src to a data: resource. Firefox and Opera only. From Dive Into GM:
- var logo = document.createElement('img');
- logo.src = 'data:image/gif;base64,R0lGODlhDQAOAJEAANno6wBmZgAAAAAAACH5BAAAAAAA'+ 'LAAAAAANAA4AQAIjjI8Iyw3GhACSQecutsFV3nzgNi7SVEbo06lZa66LRib2UQAAOw%3D%3D';
- document.body.insertBefore(logo, document.body.firstChild);
- Embed an XBM file. Yes, some browsers can display XBM images. Works on IE and Firefox, but not Safari or Opera. Unfortunately, XBM has the rather major constraint that it’s black-and-white. However, it does have the virtue of being a plain-text format which, like the data: protocol, you can assign an image source to.
If you get your image data in that format in a string (complete with the n after each of the #define lines), then you can make any image’s SRC attribute be:
“javascript:'”+xbmimagestring+”‘”XBM’s not used often, but there are some nice examples: Wolfenstein 5K, most notably, as well as this bitmap editor and a sparklines library.
(Off-topic: I’ve just updated my blog page, I prefer the 2-column sidebar because: (a) there are now 20 monthly archives links; (b) I wanted to add a ton of chicklets; (c) I wanted to add more bio info. BTW If you have a blog, here’s a quick exercise: Place yourself in the mind of a new visitor for twenty seconds, and decide if this person could work out who you are, what you do, and how to contact you. Around 90% of blogs fail this test on the grounds it’s impossible or way too hard.)
data: URI:s are not Firefox only; Opera supports them too since at least version 8.
broad range of SVG links: http://svg.startpagina.nl
Johan, that’s fixed, thanks.
Also, there’s the High Performance JavaScript Vector Graphics Library by Walter Zorn which probably falls into #6. http://www.walterzorn.com/jsgraphics/jsgraphics_e.htm
dzsino
What about the GD library for PHP? You can do some prett amazing things with that, and coupled with Ajax the possibilities are almost limitless. Plus it has the advantage of not requiring any special plugins or capabilities for client browsers, just the GD library/module installed on the PHP serving server.
There’s more links at xdraw.org, plus some examples of unified APIs. The 0.4 dojo toolkit will have dojo.gfx, a cross-browser SVG/VML javascript API for graphics coding.
The GD library can produce some great stuff on the fly, and it works quite well. Although it can use a large amount of memory during operations, so a continuous feed from AJAX requesting new data would completely kill the system.
Keeping in mind that a GD image sized around 1600×1200 can use up too 32MB of memory. Most PHP installations refuse to use more than 32MB of memory operation without some tweaking.
SVG isn’t completely natively supported in Opera or FireFox. Whilst they both support the basic elements, they have limited support for things such as Outline, Filters and other affects. Some implementations are quite buggy.
Strangely, with the Adobe SVG plugin, Internet Explorer posses the best SVG support to date. Lets hope SVG increases in popularity and other browsers increase their support for the standard.
Flash is the most powerful browser graphic platform ever existed. But somehow, there is always a voice in my head telling me not to use flash…can anyone refresh my memory on why flash is not everything we need?
coolnalu, the main argument against Flash would be the user base – not everyone has it, some people have older versions, and some companies have policies against running it or upgrading it. From the Richer Plugin pattern…
A standard plugin platform has the following advantages:
However, there are also advantages of writing your own plugin:
Pingback: nonsmokingarea.com » Blog Archive » dev: create on-the-fly graphics on websites
Let’s not forget storing an image as a BLOB in mysql and then dynamically sizing or croping it with DHTML at runtime. I wouldn’t want to do this with a large number of images, but it’s still valid, flexible and fairly easy to code into a div or iframe tag.
GVD, That’s a good point – using CSS background offsets to choose an image (described in AjaxPatterns “Sprite” demo wrt DHTML Lemmings), that’s really a very different kind of CSS usage from that mentioned above, and constitutes another technique.
Why don’t you just store the graphics as vml and convert on the fly to svg using the Xml Stylesheet Language? See http://www.cs.unibo.it/~zonta/TESI/XSL/ for an example of this XSL stylesheet I found.
Instead of using JavaScript to generate the dynamic SVG, I have a discussion of using XSLT to render the SVG from the XML returned from an AJAX request at http://pothoven.blogspot.com/2006/05/inline-dynamic-svg-from-xml-with-ajax.html
The are also several additional posts which are linked to from that post which deal with some problems I encounted in IE and Firefox.
ZDNet on the comments above wrt Flash
@Lachlan, Adobe have dropped the SVG plug-in for IE. If you’re interested in this article I suggest having a look at the source code to mxGraph – http://www.mxgraph.com. This is entirely SVG and VML renderering, with a lot of performance tweaks to get the thing going fast enough.
An example of technique number 6, combined with real-time server-pushed data through the Comet paradigm is visible here (based on Lightstreamer): http://app.lightstreamer.com/ChartDemo/
Pingback: Jeff Barr’s Blog » Links for Monday, November 13, 2006
Pingback: All in a days work…
Pingback: j’Alias » 8 manières de dessiner en JavaScript
no more XBM support in IE 7: “Functionality Removed and Changed in Internet Explorer 7 … XBM–Support for XBM, an imaging format designed for X-based systems, was deleted.”
I am trying to do something which has not been done as far as I can tell. I have written a computer program which is a complex curved shape generator. A CCSG. I just made that term up as I am writing this.
I would like to know what technology will do the following: 1. Be generated and held in the browser. No server. 2. Supported by most browsers. 3. Small amount of libraries needed. 4. Does not use up too much computer memory and render in a reasonable amount of time.
Right now I am going to literally modify the JavaScript Vector Graphics Library by Walter Zorn. Because what I am drawing is essentially an extremely complicated ellipse. http://www.walterzorn.com/jsgraphics/jsgraphics_e.htm
I am wondering if dojo (svg) or canvas would be better, or do they all do things in the same way? For example, Zorn stores hundreds of s to render one ellipse. I am doing my development using Firefox. But I plan to test it on IE and Opera.
I also noticed that there is no visual tool (other than CodeGear) which one can use to design forms for the Web application (drag and drop controls).
Interesting post. I’ve been looking for a way to put in an ad link that corresponds to an image. For example, an image of a theme park will have a dropdown ad that links to purchase tickets or for more information. A close example of this is britepic, although I am looking for open source scripting that will allow me to put in my own ads with my logo in the corner and not a 3rd party ad. Anyone know how to do this??
Hi Andrew, the path you’re following sounds sensible, though there’s not much more I can say than what’s in the above post.
Sandy, I’m not sure exactly what you’re after, but it sounds like it might require Flash???
As a small variation on #6, create a table of single pixel divs. The table can be built up in Javascript, storing references to the pixels’ style in a 2D array along the way, then the pixels can be changed by setting the background:
pixelgrid[0][0].backgroundColor = ‘blue’
I haven’t seen anyone use this yet. Walter Zorn’s library at http://www.walterzorn.com/jsgraphics/jsgraphics_e.htm could probably be adapted quite easily, and this might be a little quicker for line/curve drawing as the div optimizations can be safely removed.
Pingback: Hanno’s Coding Log » Blog Archive » Dynamic Graphics in AJAX applications
Does anyone have any information regarding defining flash graphics from an external xml file. For instance, I want to define, background colors, stroke color, positions, font colors, font type, padding. Basically almost everything that CSS can do, except through XML using Flash?
Pingback: Software As She’s Developed » Blog Archive » Announcing Bitjuice: Ajax Bitmap API
Best VML / ajax performance .
Here is the first browser game, that use VML and Ajax to achive real time interactivity of multiple players and astonishing special effects with large number of true transparency layers.
game play movie on the main page. http://www.glory-online.com try it.
game run on 3 servers.
Pingback: Ajax/Javascript: 8 Ways to Create Graphics on the Fly » Agile Techno Solutions ., JSC
http://jsdraw2d.jsfiction.com is another javascript graphics library which draws with divs. It can even draw curves with tension parameter and beziers. Moreover it provides options to set origin, co-ordinate type and scale for the drawing.
Pingback: ePva's blog » Dessiner avec du JavaScript
http://www.demonplates.com/platebuilder.php
I recently came across this site. I think they have used Ajax for developing the plate builder tool.
I am perplexed – please guide me how this tool can be developed in anything other than flash
Walter Zorn’s website has moved to http://www.walterzorn.de/en from where his software can be downloaded. His old site no longer exists. The links to it in the above posts are presumably obsolete. The reason why his site has moved can be found at my site http://www.bjarne.altervista.org together with an example of how Walter Zorn’s software can power an interactive user interface.
Pingback: Creating SVG graphics using Javascript? | ASK AND ANSWER