Shared publicly  - 
 
SVG sprite-sheets and HW accelerated animation

I spent the last few days playing around with SVG. The idea was to see if I could come up with single-source resolution-independent animated characters that would play and look good on everything from a smartphone, to tablets, retina displays and desktops. In the browser of course - specifically mobile browsers.

I actually wanted to test out the idea of combining traditional sprite-based animation with SVG (not SVG-based SMIL animation) + add some transform3D into the mix for HW acceleration on mobile.

The result is somewhat surprisingly pretty fast (http://bit.ly/J16hki) - a complex animated vector-only character with gradients of 12 frames running at 600x600px. Had no idea SVG had come that far. Note that this is only for Webkit browsers (Chrome, Safari, Android ICS, iOS) - could probably make it work on others too, but it was just a test.

And yes, its loading a pretty big/complex SVG file (around 400kb) but this was intentional too - if it works with something like this, it will probably work with more optimized stuff too. The frames were exported from a Flash animation (SWF) and individual SVGs optimized in Inkscape/manually.

I'm pretty happy with the result but its still not usable to the extent I'd like it to be (works for smaller sprites but we're still not anywhere near retina):

⚫ in Safari there is a fair amount of flickering at the beginning (I'm guessing until everything is loaded into memory/gpu) and then it becomes smooth - in mobile Safari on my iOS5 iPad2 the same thing (no matter the flickering at the beginning - happy to see such a large animation run so smoothly)

⚫ in Chrome it runs smooth but if I crank it up to a larger resolution (than 600x600) I get funky lines all over the place (GPU struggling?) but it still remains smooth

⚫ in Android ICS browser its flickering all the time so its not usable there but its still surprising to me that its running fast i.e. without dropping frames there

Its great because I tested an output out of Google Swiffy (http://bit.ly/vYYz8o) which takes a slightly different path - but its too slow on mobile platforms. Adobe Wallaby (http://adobe.ly/i3eP1o) is pretty fast - it works with individual SVG sprites which are animated in CSS3/HTML5 (in theory better than frame-by-frame sprites - but subject to browser whims) - but its completely unflexible and unpredictable (plus it seems to be a dead project which is a shame as it showed a lot of promise).

Thats why this brute-force CSS-only (translate3d) SVG sprite sheet approach surprised me - it actually performed better than many other solutions. At all it took was a few lines of CSS. But like I said still not perfect.

However, there are a few things that made me hope it could be optimized/fixed even further.

⚫ at first I thought its because my SVG is too complex and the browser can't cope with rendering and drawing at the same time. Thats when it occurred to me that I could load SVG to the size I'd like it to be and then use scale3d to dynamically convert vectors to rasters since Webkit treats scale3d transformed elements as textures instead of vectors. So scale3d(1, 1, 0) wouldn't resize anything but would in theory cache my SVG into raster data. Funny story here scale3d(1, 1, 0) works perfectly in Safari - but will not load on mobile Webkit (on iPad/ICS) - you have to add Z i.e. scale3d(1, 1, 1) - but then the technique doesn't work any more (reverts to flickering) even on desktop Safari :)

⚫ thats when I decided to test this with a much simpler approach - manually switch my SVG file with a PNG/JPEG rendered bitmap of the same animation. Unfortunately - this didn't do a thing - flickering still remains.

Which means that its not about SVG rendering/parsing at all - its about browser drawing. I'm of course not complaining that about not being able to draw at full screen 20fps in the browser :) - just testing the limits :)

Anyway - thats the point of this post - anybody has any ideas how to make it even faster or get rid of flickering? Or is this the speed/performance limit? I'm playing the community card - many heads are better than one and all that :) +Paul Irish? +Ricardo Cabello?

Translate3d is the fastest thing on mobile of course - but I tried a few other things like just animating left, background-position anyway. That doesn't flicker but its of course not usable on mobile where it crawls. Have also tried playing around with having a smaller base image and then scaling it up + a few other pointless hacks.

I guess I could try a few other tricks like clip:rect() or drawing SVG onto canvas - but somehow I don't really think that would be faster. If I could only get rid of the flickering.... maybe the image/texture is simply too big? I wonder if it would help having multiple smaller images and then attaching them as multiple background-images to the same container. Or maybe just doing everything in SVG/SMIL and try to let the browser chew on that?

Yes animating smaller SVG images in CSS/JS would work better than full frames - but its also more complicated. Plus a benefit of spriting/animating full frames is that you could reuse a lot of old SWF animations (+ Flash still has probably the best editor for animation). Was hoping for a seamless workflow there - to much to hope I guess :)

Dunno - community card! If you have an idea and like to play with some cutting edge stuff - please speak up ;-)

#svg #spritesheet #webkitanimations #webkit #webkittransform #css3 #html5
17
2
Christophe Schwyzer's profile photoDan Hill's profile photoWolfram Kriesing's profile photoVeljko Sekelj's profile photo
8 comments
 
Hm, have not tried directly writing the SVG sprites with JS yet - this was a CSS only approach until now. I figured canvas would be slower because there is an extra drawing step in between.

Plus nothing I've tried that was canvas-based has really impressed me with performance on mobile browsers (at least in terms of drawing images so large). But you're right of course - I did all these work testing - it would be a shame not to do this extra step and check out canvas performance too. Will do that today.

BTW you're on Chrome on Linux right? How is it running for you?
 
BTW2 - the weird thing is - it doesn't seem a performance issue because I can slow the whole thing down to draw just 1 FPS or slower and I'll still get the same flickering on the first few frames. Probably a GPU-drawing issue - perhaps its just too much to hold in memory... :-/
 
I am trying your speed tricks, to squeeze some out of SVGs too.
you might be interested in http://bonsaijs.org, basically a simple API for drawing and more, its currently rendering out everything into SVG, we use it as our core to convert flash to html5, and when there is a canvas renderer it would be interesting to compare
 
Really like your experiment. The flickering seems like a browser drawing / memory issue to me, bc it works without flickering as you decrease the size of the "animation box" or simplify/reduce the sprite file. (tried santa with 160x160 and it worked on Safari)
 
+Christophe Schwyzer thanks! yeah I know that if you decrease the size it stops - seeing how far I can push the size was kind of the point :) 

+Wolfram Kriesing thats a very cool service you're building + thanks for the bonsaiJS tip... BTW if it helps - I've been able to push it a bit more by just using an embedded IMG tag (rather than background-image on an element) - check out http://bit.ly/SZdIMr ... I'll have to do a bigger post on that one of these days :)
 
very nice! i have been experimenting a bit with the timeline and some of your tricks, and you can see that the impact of what is updated can be reduced, which is nice to see, and that you can push more stuff to "Composite Layers" which seems to mean its rendered in the GPU, thanks for kicking it off with your experiment
 
Have you tried preloading the assets with jQuery before you run the animation or even draw it's container?  $("<img/>").load(function(){init();});
 
If you test the animation on Android Chrome (version 29.0.1547.72) there is no flickering. Using the android standard internet browser on Galaxy tab 10.1 (GT-P7500 Android version 4.0.4) the animation flickers. This is a great problem for Cordova/Phonegap applications using svg css keyframes animations.
Add a comment...