Robert, 22 May 2010

Hand-drawn annotations: writing on the page

We've spent an interesting couple of months getting to grips with the various ways of collecting and displaying freehand annotations. If all browsers supported the canvas element then life would be rather easy but, sadly, that's not the case. On the bright side, however, the two technologies you need for Internet Explorer, VML and Silverlight, are both interesting in their own right.

VML has been around for many years in the IE family, but it seems not to be used much presumably because other browsers don't support it. Essentially, you just compose a chunk of XML specifying the item to be drawn and insert this text into an element on the page. The XML format is not exactly beautiful, but on the other hand it does have the advantage of being a display oriented rather than a drawing oriented mechanism. You can just modify the entity to be displayed and the browser sorts it out, whereas with a canvas you manage the redraws yourself with low level stroke and fill operations.

We wondered about just using the Google code ExplorerCanvas which translates normal canvas operations into the corresponding VML but decided against it for a number of reasons. Its strength of course is that you just need the one codebase. Downsides for us were performance (its good, but not as good as optimizing the VML creation just for the specific operations you use), size (we don't need that much generality and we want to keep the volume of javascript as low as possible), and some unimplemented behaviors to do with image transparency and dynamic resizing.

The nice surprise in all this though was Silverlight. This is the only place we're using Silverlight in A.nnotate but I was pretty impressed. Strictly speaking, it isn't essential for what we do: you can track mouse events with javscript and echo them with VML. Indeed this is what will happen on Internet Explorer if you don't have Silverlight installed. But Silverlight does give two big wins:

  • Pressure sensitivity: if you've got a pressure sensitive device like a graphics tablet or a tablet PC, Silvelight will give you the pressure as well as the position.
  • Batched events: you don't just get one call per point as the mouse or stylus moves. You can get a whole array of high resolution points in a single call. This means that the sampling rate can be higher than if every new point has to go back to JavaScript to be saved and rendered.
And, it's remarkably easy to integrate with JavaScript. Twenty lines of XAML gets a definition of the input canvas and ink; another chunk defines the Silverlight object. Generating the content to go on the canvas is much like the VML process but with different element names. After that, you can get JavaScript references to the Silverlight elements (canvas, image, image transforation, ink, etc) and just operate on them from JavaScript as though they were a new bunch of rather exotic DOM elements. All in all, rather a painless integration!

The hardest thing in all this is working out how hand drawn annotations should actually work to make it intuitive for the user. Do you just want to be able to draw on the page, or do you want to select where to draw first and then zoom and pan before making your mark? Our conclusion is that probably both are needed. For signing a document using a graphics tablet, you probably often want to zoom and adjust the box before you sign. Other times you may just want to draw on what is there. Both are now possible in the development version of A.nnotate. Watch this space for announcements about the public release or get in touch for a demo.

You can draw straight on the page...

...or pick a region and zoom in for finer control.