The idea

The other day, I took it upon myself to write a browser-based Prezi-like app without using flash. Condition: It should run purely client-side.

It was also an experiment in evaluating whether the current APIs available in modern browsers are enough to handle the task. What follows is an account of what works, what doesn’t, and what could be done better.

SVG vs Canvas

When you’re building a rich graphics-intensive app like Prezi, you usually have two ways of rendering content: SVG and Canvas.

1. SVG provides a neat DOM that can be manipulated with existing DOM handling javascript libraries, such as jQuery. Canvas, on the other hand, is just a bitmap buffer. This means that you have to program your own DOM-like scene graph if you wish to use Canvas for handling presentation elements. Libraries for this already exist – most notably, fabric.js, but none are as convenient to use as a real DOM. SVG wins here.

2. Canvas is just a dumb bitmap buffer. Animating it is faster than animating SVG with Javascript, but it isn’t accessible. You can’t select text with the mouse. You can’t embed rich content. SVG wins in this regard; you can even embed YouTube videos and forms and such.

3. SVG is not implemented as completely or identically across different browsers as Canvas is. The worst offender here is, of course, IE9 (a lack of SMIL animation support, among other things). Text rendering looks noticeably different in every browser. This can be mitigated somewhat by not allowing the browser to use default fonts, but using custom webfonts like Google’s toolkit. The rest of the rendering should look fine if you stay away from edge cases (literally) such as not drawing objects outside the main SVG canvas, for example:

<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="100" height="100">

<rect x="10" y="10" width="50" height="80" rx="-10" ry="-10" fill="red"/>

</svg>

4. SVG and Fonts are not friends. Everything is supposed to be vectorized, but fonts aren’t handled that way. If you notice the animations in the example linked to near the end of this post, you’ll see that during zooming, the fonts ‘shake’ when resizing, because they don’t scale smoothly as normal vector content. The only way to achieve smooth scaling is to convert the text to paths, but that defeats the purpose of text accessibility. There is an SVG Fonts spec, which aims to remedy this by having each font glyph rendered using SVG paths, which would mean real vector fonts which can be selected with the mouse and handled as normal text, plus identical rendering everywhere. Webkit and Opera support this spec, but Mozilla and IE have outright refused to implement it, with the explanation being that WOFF is a ‘superior alternative’ or ‘enough’. This is quite wrong and their arguments are not satisfactory. WOFF is not vector content, and therefore can’t be (and isn’t) rendered identically everywhere. Period.

Taking 1 and 2 as points in our favor, and tolerating 2 and 4, I chose SVG to be the superior but not polished-enough alternative.

Animation

Next, we want to animate. We won’t use CSS3 animations (not supported well enough everywhere). SMIL animation is fast, but works only with non-IE browsers. Heck, we’ll just use plain old JavaScript. I’m using Sozi‘s javascript code for animating.

The Editor

We want to make an SVG editor, in which after designing the document, we can choose certain elements to be nodes in the presentation path, and then have the editor inject the JavaScript code required to animate the presentation.

As it turns out, SVG-edit is an open source, completely client-side SVG editor, and perfectly suited for the task at hand.

I decided to take it’s core and build on top of it, stripping out the unneeded parts and adding some more useful features. It looks like this right now:

And here’s a link to the presentation shown above.

Rendering the Timeline

The sidebar on the left is supposed to show a strip of ‘snapshots’ of nodes in the presentation path, such as what Prezi shows: And here’s a similar sequence rendered in Awwation: The strip is generated using a hack. Due to browser security policies, you cannot render an SVG as an HTML5 Image and crop a region out using Canvas. So I had to use canvg, a client-side javascript library that tries to read SVG and render it onto Canvas. The code then converts the Canvas context to an image and adds it to the strip. It doesn’t work perfectly – if there’s external content in the SVG, such as an xlink’d image, it won’t render and you’ll get blank snapshots. Apparently the only perfect way to render snapshots is to actually send the SVG to the server, use PhantomJS to rasterize it, and send it back to the browser. But this defeats the purpose of doing everything client-side, so that’s a no-go. Theming Disclaimer: I haven’t done this one yet. Prezi has a presentation themes collection. This is where Awwation can totally beat Prezi, and here’s how: CSS themes. SVG can be easily styled using CSS. WOFF fonts can be embedded as dataURLs in the CSS code. Anyone can create CSS files for this and you could have a huge user-generated corpus of themes! Collaborative Editing SVG-edit has already been extended to have real-time collaborative editing features using the Google Wave protocol. So Awwation can get collaborative editing for free! (once I or someone gets around to integrate it). Saving Since we’re doing all the work client-side, we don’t want to send the created SVG to the server and then download it back to the client’s file system. We want it saved to disk right here. This would be the ‘normal’, convoluted way of doing it, but fortunately there is an implementation of the proposed HTML5 FileSaver API which allows us to save the file directly from the browser to disk. Unfortunately this works perfectly only on Chrome. With Opera/Firefox, you’ll have to save the generated file, rename it to .svg, and then view it in the browser. Conclusion This can be much more capable than Prezi in terms of accessibility and extensibility. Holding it back are security policies and inconsistencies across browsers, which will hopefully have workarounds in the future. Finally, Here’s the project page for Awwation: http://adityab.github.com/Awwation/. Here’s a link to a sample presentation using Webfonts to make it look consistent across browsers: http://dl.dropbox.com/u/40496552/awwation-intro.svg. Warning: The presentation doesn’t work in newer versions of opera at the moment, here’s a relevant issue in Sozi. PS: I was inspired to work on this idea from Calligra Stage’s similar project.