Awwation update: Live thumbnails!

In my last Awwation update I talked about the new CSS Themes support.

This time, I have another improvement. In the old version, the timeline strip had bad thumbnails. I was using canvg to render the SVG onto a Canvas and then drawing the Canvas bitmap as a snapshot:

Old strip. Bad snapshots.

This time, I’ve dropped the Canvas approach altogether since I discovered the <use> SVG element. <use> allows you to ‘href’ to an SVG element residing in the DOM and display a ‘reference’ to that SVG. You can also add overriding properties such as a viewBox and transforms.

In action:

New awesome strip. Live, moving, 100% accurate snapshots.

Now you can pick any element as a path node in the presentation timeline, and a snapshot of it as it exactly as it appears in the document, during the presentation, will be shown in the strip. How is this better than Prezi’s strip? Well, here, changes are reflected as they happen – so, if I’m moving an element around in the editor, you can see it moving around in the strip too!

Awwation update: Themes support

Last week, I blogged about how I wrote the first iteration of Awwation, an HTML5 Prezi clone. Somehow the blog post surfaced onto the front pages of Slashdot, and /r/programming for a couple of days, and the project got a decent following on Github (it was a trending repo that day!).

This prompted me to polish the code a bit to make it presentable to potential contributors, and now the app is in a somewhat usable state.

The first iteration was rather bland, so I thought it would be a good idea to have presentation themes like Prezi does. As it turns out, this was easy – SVG can be styled using CSS.

So here’s a sample CSS theme for Awwation:

@import url(http://fonts.googleapis.com/css?family=Berkshire+Swash);

text {
    font-family: 'Berkshire Swash', cursive;
    text-shadow: 0px 0px 8px rgba(150, 150, 150, 1);
}

rect {
    stroke: #AEAEFF;
}

ellipse {
    stroke: #FF0000;
}

That’s it, really.

And here’s a new ‘Themes’ menu, with the above theme in action:

Themes menu. Selecting a different theme instantly changes all elements in the document to the new style.

What next? A theme creator tool would be a good idea. I’ve opened an issue for that. Contributions are welcome.

Writing a Prezi clone with HTML5, SVG, and Javascript

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>

Difference between SVG rendering across browsers (source)

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 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:

The editor. Incomplete, but it works.
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:

Prezi strip. Nice snapshots.

And here’s a similar sequence rendered in Awwation:

Awwation strip. Okay snapshots.

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.