For years, web developers have asked the question, “How can I draw in the browser?”. This simple question has anything but a straightforward answer. While the image tag is great, CSS is amazing, and Flash gets the job done, it still is not enough. What I’ve wanted for almost a decade is the ability to draw and modify non-rectangular, browser-native shapes in my web sites. And I want to do this without having to use a graphics editing tool and reloading images from the server. I simply want the ability to manipulate, draw, and connect events to arbitrary shapes and styles, to create rich, sophisticated web user interfaces.
Landscape changes to web applications have been drastic with the widespread adoption of the XMLHttpRequest and other AJAX and Comet techniques. In my opinion, asynchronous, low-latency data transit (AJAX and Comet) paired with vector graphics opens up a world of new opportunities for web application development. I’m obviously not alone in this desire for browser-based drawing solutions, given the wide variety of image techniques and CSS hacks that have evolved over time.
Despite a history of W3C effort towards the SVG specification, there was little support among browser vendors until now. Apple, the WhatWG, Mozilla, and Opera have been working in parallel on Canvas, a simpler but less feature-rich procedural vector drawing API.
After years of frustration, we finally have enough support to create a simple, unified, cross-browser drawing API: dojo.gfx is the newest piece of the Dojo Toolkit and is an amazingly powerful yet simple way to accomplish these goals. Browser support currently includes Firefox 1.5 , Internet Explorer 6 , and Opera 9. Safari fans fear not - support is underway with the latest WebKit nightlies, and is expected to be functional with the next major release of Safari in 2007.
If you want to skip straight to the examples and source code, there is a collection of resources at the end of this article. Otherwise, sit back and enjoy the code!
What Does dojo.gfx Do?
In a nutshell, dojo.gfx lets you draw natively in the browser with an easy to follow JavaScript API. Let’s start by simply drawing a blue rectangle and a green circle:
var node = document.createElement("div");
document.body.appendChild(node);
var surfaceWidth = 120;
var surfaceHeight = 220;
var surface = dojo.gfx.createSurface(node,surfaceWidth, surfaceHeight);
var rect = { x: 100, y: 0, width: 100, height: 100 };
var circle = { cx: 150, cy: 160, r: 50 };
var group = surface.createGroup();
var blueRect = group.createRect(rect)
.setFill([0, 0, 255, 0.5])
.applyTransform(dojo.gfx.matrix.identity);
var greenCircle = group.createCircle(circle)
.setFill([0, 255, 0, 1.0])
.setStroke({color: "black", width: 4, cap: "butt", join: 4})
.applyTransform(dojo.gfx.matrix.identity);
As you can see from this basic example, the first step is to create a gfx surface on which to add nodes that you will be drawing. It’s then possible to add shapes to the surface, and apply styles and transformations in a chainable manner. They are applied in the order defined and provide a concise yet flexible opportunity to style, fill, and transform your nodes. People familiar with vector graphics will immediately notice that we are using the same general concepts found in SVG. You will also notice that we have gone to great lengths to keep our syntax concise, using JavaScript literals for our property definitions.
What Time Is It?
A more complex and engaging example is the Dojo clock widget, developed by Dojo contributors Eugene Lazutkin and Tom Trenka:

The clock widget shows the flexibility of the Dojo widget system in non-HTML namespaces. The following code fragment demonstrates the straightforward method by which hour and minute hands are placed, including realistic shadows:
this.shadows.hour.shadow = this._initPoly(this.surface, hP)
.setFill([0, 0, 0, 0.1]);
this.hands.hour = this._initPoly(this.surface, hP)
.setStroke({color: this.handStroke, width:1 })
.setFill({
type:"linear",
x1:0, y1:0, x2:0, y2:-27,
colors:[{offset:0, color:"#fff"}, {offset:0.33, color:this.handColor}]
});
this.shadows.minute.shadow = this._initPoly(this.surface, mP)
.setFill([0, 0, 0, 0.1]);
this.hands.minute = this._initPoly(this.surface, mP)
.setStroke({color: this.handStroke, width:1 })
.setFill({
type:"linear",
x1:0, y1:0, x2:0, y2:-38,
colors:[{offset:0, color:"#fff"}, {offset:0.33, color:this.handColor}]
});
Circle Frenzy
An example showing the powerful use of the Dojo event model with a complex dojo.gfx layout is the draggable circles demo developed by Dojo contributor Gavin Doughtie:

Two dojo.event.connect calls are used to handle mouse events, which then call some simple functions to detect which shape was selected, handle mousemove events for dragging a circle, and then canceling a mousemove event when the mouse button is released. This is in fact the single biggest advantage of dojo.gfx over Canvas… items drawn with SVG/VML are normal DOM nodes in your document, to which you can easily connect event handlers.
dojo.event.connect(this.domNode, 'onmousedown', this, "handleMouseDown");
dojo.event.connect(this.domNode, 'onmouseup', this, "handleMouseUp");
getShape: function(evt){
var id = evt.target.getAttribute('shapeid');
var s = null;
if (id) {
s = this.gShapes[id];
}
// dojo.debug('target: ' evt.target ' id: ' id ' shape: ' s);
return s;
},
handleMouseDown: function(evt){
dojo.debug("got an event");
var shape = this.getShape(evt);
dojo.debug(shape)
if (shape) {
this.gCurrentShape = shape;
dojo.event.connect(this.domNode, 'onmousemove', this, "handleMouseMove");
dojo.event.browser.stopEvent(evt);
}
},
handleMouseMove: function(evt){
dojo.debug("mouse move");
dojo.debug(this.gCurrentShape);
if (this.gCurrentShape) {
var pos = dojo.html.getAbsolutePosition(this.domNode);
var x = evt.pageX - pos.x;
var y = evt.pageY - pos.y;
dojo.debug(x "/" y);
this.gCurrentShape.setShape({cx: x, cy: y});
dojo.event.browser.stopEvent(evt);
}
},
handleMouseUp: function(evt){
this.gCurrentShape = null;
dojo.event.disconnect(this.domNode, 'onmousemove', this, "handleMouseMove");
}
Which Features Are Supported?
Strokes
In HTML, we generally call this a border, but in vector graphics, it’s a stroke, because it can be a border of an element, or also the edge of anything, including a custom font. Strokes can be hidden, or set to various colors and widths. We also provide the ability to set join parameters, which define how lines come together at edges. You’ve probably noticed the latter, but had little control over it when using thick borders in HTML elements.
Fills
A fill is both background and foreground rolled into one. Transparent fills are supported though not particularly interesting in this discussion. Solid colors are nice and even more interesting are linear and radial gradients with various starting and stopping points. While you cannot create every imaginable gradient today (because SVG and VML do not yet support gradient fills beyond linear and radial), there are a number of clever techniques, using layers and opacity, to achieve most 2-dimensional gradient effects.
Shapes and Paths
dojo.gfx provides a number of commonly used shapes including rectangle, ellipse, line, and circle, as well as the ability to draw along any path. Shapes are simply a special case of a path, which supports simple point to point options, as well as complex cubic and bezier curves.
Opacity
Most browser implementations of this feature in HTML are limited to an opacity that is the same for background and foreground. With dojo.gfx, we can define full alpha opacity on the stroke and the fill, together or independently, providing much greater design flexibility.
Linear Transformations
Rotation, skew, move, resize, and more, are all possible with linear transformations and are based on standard matrix algebra. dojo.gfx exposes this API to make just about any transformation possible. And while dojo.gfx is a two-dimensional API, I have no doubt that people will become inspired to develop three-dimensional transformations using the two-dimensional transformation API.
Rounded Corners
What drawing API would be complete without the ability to draw rounded corners? dojo.gfx provides a simple API for doing just that. Say goodbye to background image hacks!
Charts
We recently announced that Dojo has APIs for live charting. These APIs are highly specialized and are not currently based on dojo.gfx. Charts were developed before dojo.gfx was ready for production. Nevertheless, they show how much is possible in today’s browsers with vector graphics. An example:
You may have noticed that I mentioned live charts. We will very soon release examples that show animated, dynamic, real-time charting. Greenplum will soon be releasing the Greenplum Monitor, a database monitoring application built on top of this code that provides browser-based server performance information, much like that which you would find in the Apple Activity Monitor or Windows Task Manager.
So, Why Not Canvas?
The number one reason, in my perspective, is that because Canvas does not have a true DOM, you cannot easily attach DOM events to a specific node or layer in a drawing. There are other minor reasons, but this reason alone makes it much easier for JavaScript developers to work with HTML and vector graphical elements seamlessly and in the same web application interface.
Are We Reinventing The Wheel?
I hope not! dojo.gfx is not yet another vector markup language, but instead it is a solid subset of SVG features and nomenclature. Like Canvas, it is a procedural drawing API. dojo.gfx is not intended to solve every drawing need ever conceived - rather, it covers the baseline technology that is widely available across today’s browsers using SVG or VML within Internet Explorer. A major benefit of dojo.gfx is that it abstracts away the numerous inconsistencies across the browser vector graphics implementations. We all know that even the best, most standards-compliant implementations of HTML, CSS, and JavaScript are inconsistent. Vector graphics suffer in a similar manner.
One of the very first design decisions of which I was a proponent was that the Dojo Toolkit not be HTML-centric. After working on several SVG-based intranet applications, I was highly motivated to see Dojo work well with SVG and other namespaces that could become relevant in the future. This decision has helped significantly with the implementation of dojo.gfx, as very little of the Dojo codebase assumes an HTML DOM.
The Future
As you can see from the demos, we are just scratching the surface of what is possible with dojo.gfx. With this simple yet powerful set of options, we have the ability to create sophisticated native user interfaces in the browser. Based on our recent work at SitePen and the expressed interest of our clients, we’re well underway to building a new field of collaborative visualization web applications. I’m really excited about the possible application interfaces that we can build with native vector graphics support in today’s browsers.
Credits
Special thanks to Eugene Lazutkin, Gavin Doughtie, Kun Xi, Tom Trenka, Mozilla Foundation, Greenplum, SitePen, and the entire Dojo developer community for making this advancement possible. Without the strong community behind Dojo, ambitious projects like this would not be ready today.
Resources
- Dojo: documentation, book, and download
- Clock: demo and source
- Circles: demo and source
- Charts: demo
- Canvas: mozilla tutorial
- Comet: Cometd, Lightstreamer, KnowNow, and DWR




[…] ThinkVitamin is now featuring my article, Create cross-browser vector graphics, an article about dojo.gfx. The article is intended to show where we are today and what is possible with dojo’s vector graphics APIs. […]
Great writeup on the APIs! On the topic on why not using Canvas, I totally agree with you that the main drawback is the immediate-mode APIs that do not allow an easy and discrete update of a graphics object. I did a little writing on why Canvas is a rather sub-optimal solution when I wrote an experimental static SVG Tiny implementation using Canvas.
Wow, this looks very interesting. Great work!
I discovered… hmm… well calling it a bug would be unfair I suppose… shall we say an “issue” :)
With the draggable circles - click, drag, move the mouse outside the rectangle, release the mouse button. Now move the mouse back inside the rectangle, and it still thinks your dragging, even though you’ve mouse-up’d.
I guess this is because it’s not catching the onmouseup when you’re outside it’s “domain”. Perhaps make it automatically trigger the mouseup when the pointer leaves the area?
On an off-topic note, does anybody else find the little screenshot popup things that thinkvitamin have added to every link, well, um… bloody annoying?
@Steve, yeah I do too, techcrunch also has them.
Great article though.
“On an off-topic note, does anybody else find the little screenshot popup things that thinkvitamin have added to every link, well, um… bloody annoying?”
Indeed
[…] Cross browser vector graphics and charts … and some cool webmaster tools. Share:These icons link to social bookmarking sites where readers can share and discover new web pages. Filed under Web by admin. Permalink • Print • Email […]
Antoine: Thanks! I had forgotten about your CanvaSVG… it’s a really informative exercise/experiment that did a great job clarifying what bothers me about canvas. In talking with Brendan Eich and some other people at mozilla, they really see both Canvas and SVG being useful depending on the use case. They just wish that the SVG spec. was a bit more focused.
Steve: Yes, that’s a common JS issue with ways to work around it. I guess given the demo nature of it I wasn’t too worried about it :)
Regarding the snap.com preview widget, I actually don’t mind it much, because it’s not an ad. I guess I’m so used to the Tab Preview extension for Firefox that I actually kind of like the preview that it provides, sometimes. I wouldn’t be surprised if there was a greasemonkey script to disable it either available or in the works!
This is rather exciting, but I really think there needs to be a GUI for creating these graphics, that will output the javascript. Just in case anyone says “OK! I’ll do that…” ;o)
[…] Cada día que pasa nos acercamos más a convertir el navegador en el centro del ordenador. Lo que nos podría llevar a una discusión sobre si debemos tender a convertir el navegador en el sistema operativo del pc o convertir el sistema operativo del pc en un navegador. Una de las limitaciones que había hasta ahora era la carencia de una forma sencilla y estándar de poder crear gráficos dentro del propio navegador. Como ya pasó con el javascript parece que por fin hay un soporte decente entre los principales navegadores y gracias al empleo de librerías como Dojo.gfx podemos crear, por fin, gráficos de forma fácil y que funcionan en los principales navegadores. […]
Gráficos vectoriales para todos los navegadores…
Gracias al uso de bibliotecas como Dojo.fx (dojotoolkit.org/) se pueden crear fácilmente gráficos vectoriales y que se muestren correctamente en los principales navegadores web. En este post se presentan varios ejemplos prácticos. En inglés….
Jon: I would love to see someone develop something like that. Of course, I can’t draw a circle with Photoshop to save my life, so I much prefer markup and script. But I know I’m not the norm!
This is exactly what WPF/E is/does ( and it is cross platform, cross browser). Your write in Javascript, and generate the XML. It then renders that and you can attach javascript events to the shapes.
Wow, very nice.
[…] Vitamin Features » Create cross browser vector graphics an intro to dojo.gfx (tags: javascript graphics dojo svg) […]
I played a bit with WPF/E a few days ago; it’s a pretty clean set of XML tags with drawing primitives, transforms, and event listeners. It would be interesting to simply transform their XML into the dojo.gfx code using an XSLT stylesheet…. Use their drawing tool for Dojo’s benefit… any volunteers?
Best,
Brad Neuberg
BTW, great article Dylan! Very well written and clear. Dojo GFX is looking damn cool; this is why I’m on the Dojo bandwagon, because Dojo bites off really cool ambitious projects like this, then works damn hard to make them real and reliable :)
I’m afraid we’re going to end up treating WPF/E like VML: a roughly equivalent (better in some ways, worse in others, non-standard in all) graphics capability exposed by the browser which must be papered over so applications don’t have to care.
As for drawing editors, my interest in the dojo.gfx project was largely informed by some experiments I made in porting the HotDraw framework to SVG. Hopefully, I’ll be able to make a “rich drawing” widget for dojo.gfx before we’re all old and gray!
How about element, which is important in Web draw? Will gfx continue to provide more complicate graphic behavior like “Clippath”?
Sorry, I just mention the text element…
Cross Browser Vector Graphics…
While I think dojo.gfx is a great idea, the javascript alone to run these are well over 150KB. Granted this isn’t too large compared to all of these javascript based frameworks that more and more web sites are using are making it harder to use fo…
Check out ZCubes (http://www.zcubes.com) . It has a rich vector based graphics tool called ZPaint that provides a GUI based paint/sketch/handwriting interface. It is currently based on VML and hence only supported in IE. But we are in the process of developing a SVG translator for multiple browser support. The vector based graphics can be drawn/edited/manipulated easily and quickly.
I thing dojo.gfx is an interesting idea for cross browser implementation, but the requirement to code (using the API) would strike out most everyday web users what want to draw on the web. At ZCubes, we strive to provide the user with simple tools and interfaces as we have done with ZPaint.
Again, please check out the website to view a large number of examples of graphical content built using ZPaint. Also, try the platform to use the ZPaint tool yourselves.
Hi Parag:
ZCubes looks like a really neat service!
I really see ZCubes and dojo.gfx going after quite different audiences. using Dojo to build a ZCubes site seems like it would be overkill. That said, it would be more appropriate for the tool used to create ZCubes sites, or ZPaint… perhaps it could accelerate your development efforts to support non-IE browsers for example!
Thanks for the handy link, it’s really exciting to see the arrival of vector graphics sites and services.
Vizjerai: It is definitely possible to optimize the code required for dojo.gfx down to around 30KB, before gzipped compression.
firefight: We will continue to make gfx support better, especially text support, which is still pretty weak in today’s browsers.
[…] Now, apparently, with the Dojo Javascript toolkit, you can generate crazy beautiful charts without Flash, and update them in real time. The flaw? Safari doesn’t support this (but it will, only in future versions) nor does IE 5.5. Still, this is the future. […]
That is incredible, I could see this being used to replace backgrounds perhaps if layering isn’t ugly, but then the question is how accessible is it? I mean will people that need like screen readers will sit back and listen to the code that draws the elements or would they be ignored?
[…] Create cross browser vector graphics (tags: css) […]
I just created a website to create WYSIWYG HTML imagemaps (http://www.kolchose.org/simon/ajaximagemapcreator/) with the vector graphics lib from http://walterzorn.com/jsgraphics/jsgraphics_e.htm
Native SVG implementations really miss good print capabilities. Opera and Firefox print rasterized for screen resolution images, while Adobe SVG plugin prints clear beautiful images.
worth a look:
Open-jACOB Draw2D. A Javascript Lib to create your own
Vision like Browser based application.
NO Plugin required.
http://www.openjacob.org
http://www.openjacob.org/draw2d
greetings
Andreas
sorry - wrong link.
http://www.openjacob.org/draw2d.html
this could be big … if it works as advertised, then great job! — you may have won me for dojo use! i’ll get my hands on it ..
if you need 2d vector (for business charting ..), are pinned on MS/IE and are not allowed to installe/distribute Adobe SVG plug-in (corporate environment/politics) — your’re pretty stuck to Flash or server-side pixel rendering techs // at least I thought .. somehow I was unaware of the existince of MS VML implementation in IE versions. That opens another avenue .. dojo.gfx.
apart, just 2 points:
a) do you (plan to) support “opera mobile 8.6 >=” (which has svg tiny 1.1 + ajax/js) — seamless vectors from desk to mobile would be really, really compelling … if not differentiating from ALL other techs incl. j2me (differetn profiles, JSR, not like j2se etc.)
b) after adobe bought macrom. neither flash nor MS will likely get any
“decent” / “std compliant” SVG support, and with MS WMF/E positioned against Flash, what do you think is the “risk” of MS deprecating VML?
cheers
t
[…] Vitamin Features » Create cross browser vector graphics (tags: svg ajax browser dojo library) […]
Fantastic stuff! I hope it will get mature soon, I’m currently using it in small graphs editing app.
Is there a comprehensive doc on all the objects, properties & methods of the dojo.gfx library? I want to use it for my development project but the doc on dojo’s site is very limited.
@Jayant: http://docs.google.com/Doc?id=d764479_1hnb2tn is our documentation in progress.
@Tobias: not yet on mobile Opera. As far as MS deprecating VML, well they did break a few things in IE 7, but they have a lot of legacy stuff out there that relies on it. I doubt even MS knows what they want to do, but they certainly have a history of hedging their bets.
@Andreas: neat work!
@FataL: I agree, printing support has to get better
@RyanB: I think we’ll need to see some adoption before screen readers are motivated to add accessibility capabilities. That said, by moving some of your code that is presentational only outside the scope of screen readers, in many ways it improves accessibility.
Thanks everyone for the great comments!
How come there is no dojo.gfx.shape.Point and Surface.createPoint()? The Polyline uses an array of points {x:, y:} so why not have an explicit Point object and support drawing of points on the map?
@Jayant: I talked with Eugene Lazutkin about this, and here are his thoughts:
“Typically it is handled with a list of points and a special marker,
which is drawn at the point location. The marker has an anchor point,
and can be a vector drawing, or a bitmap. Usually markers are treated
specially when scaling — markers are not scaled at all or, can be
scaled using a special algorithm for scaling (e.g., markers unchanged in
most cases, but when you reach a certain density, you replace them with
so called “micro-markers”, and later on they can be replaced with a
density map overlaid on the top of the picture). That was the reason why
they are not here at the moment — we need to decide on technicalities
of scaling. The simplest way is to treat them as normal picture
elements, which can be scaled.
To sum it up: this is useful, and we need to add markers to dojo.gfx.”
Thanks Dylan, I have several more concerns/questions… do you want me to post them on the dojo forums or continue here?
@Jayant: you may either post them here, send them to the Dojo forums, or send me an email, dylan -at- dojotoolkit with a dot org at the end.
How come there is no dojo.gfx.shape.
[…] We see constant useless drivel on ajaxian, techcrunch, etc., to the point where I rarely read comments any more. A rare exception to this was the set of comments on an article I wrote last year about corss browser vector graphics, where the bulk of the comments were quite useful and engaging. Sadly, this is the exception, not the rule it seems. […]
gratuites jeux yahoo…
It seems budget line cash advance poker gratuites sans inscription…
free polyphonic ringtones free polyphonic ringtones for sony ericsson free polyphonic ringtones for nokia phone…
…
cell phone ringtones wallpaper…
Unhappily motorola razr v3 ringtones cingular free phone real ringtones…
(, , Sohbet
thank you…