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