Sprite Animations on CSS Transitions, revisited12
…and I’m back! Not content with the hacky previous solution of animating spritesheets in CSS and with the help of the fabulous Doug Neiner, I created four individual ways to animate sprites via CSS3 Animations, which each of them having their own advantages. There goes the list:
background, stepped
This is by far the cleanest solution, and the solution I recommend for desktop browsers. It animates the background position, doesn’t involve any hacks and uses the new step-start easing property to disable easing, which, I found out, is implement in latest WebKit and Chrome already. Woot!
background, eased
Unfortunately, not all browsers (i.e. Safari, on both iPhone and iPad at least) support the step easing functions at this point, so a workaround is still required here. However, Doug Neiner found a better hack than me, which goes like this: Instead of doing the crappy resizing, simply double the keyframes and have a very low percentage keyframe before every change, which tricks out the easing. I recommend reading the source of the demo to get a clear picture. It rocks, and works reliably!
translated, stepped
I really really wanted to see if it was possible to accelerate animations on browser that feature hardware acceleration on CSS Transforms – in particular, iPad and iPhone’s Safari. As it turns out, it is possible – simply add an inner <div> resize it to the spritesheet full dimensions and put the background image there, set the parent div to overflow hidden and animate using translate3d(x,y,0). This, as it turns out, gives roughly a 300-400% performance increase on iPad – not bad, huh?
translated, eased
Might be obvious already – the above is great, but still looks broken on iPad. So again, we are using the brilliant little hack Doug came up with.
That’s it (harhar!), enjoy: Demo (run this on any WebKit browser)
12 Comments
handloomweaver on December 15th, 2010
Absolutely awesome work Paul (n Doug)!
Outofscope on December 15th, 2010
Great findings!
Question 1: How do You measure CSS animation performance, especially on iOS-devices?
Question 2: Is it possible to hardware accelerate javascript+css animation?
Marek Pawlowski on December 16th, 2010
Really great job!
On my iPhone4 I have flicky effect for animation which use “step-star” timing function and indeed animation is faster but a little bit crappy behavior. Is there difference between iPhone and iPad Safari?
I create also simple test case with 100 animated elements and on my device win solution with background-position. It seems that 2 times bigger number of DIVs for “translated” solution is too much for iPhone Safari.
handloomweaver on December 16th, 2010
I’m surprised we’ve not had more comments given how significant this is. Right now all the emphasis seems to be on the HTML5 canvas element which runs like a dog on mobile devices right now. This is CSS & Hardware accelerated on iOS & other mobile devices. This is huge!
Marek Pawlowski on December 17th, 2010
I’ve just created some test cases for solution which covered in this post and add my own cross-browser implementation of sprite animation.
Paul on December 17th, 2010
@Outofscope: I honestly don’t know how to accurately measure CSS animation performance
I’ll ask some folks at Apple soon enough. I didn’t understand the second question, I’m afraid.
@Marek: the step-start easing is not yet supported on iPhone/iPad, that’s why it’s flickering. In production (in our game engine), the winning workaround for now was to still use background-position shifting (hence saving nodes), but applying a 3d translate on the element, which magically enforces acceleration on the compositing.
Outofscope on December 17th, 2010
@Paul I mean, is there a possibility to be hardware accelerated (for some performance gain) for the sprite animation performed not by CSS transitions, but by a javascript (e.g. changing bg-image or div coordinates with a script).
Also, how do You know, the animation is acceleratad or not? By looking at FPS or CPU usage? Or there are certain rules/circumstances?
Marek Pawlowski on December 17th, 2010
@Paul @Outofscope It’s not real enterprise solution for measure performance rather “empirical” one. But You can put 100(n) elements with particular solution and watch what happens. What is the numer of the animated elements which significantly broke down user experience or crash the browser ;/// Just try to perform typical user actions like scrolling, changing device orientation, zoom in/out etc.
Marek Pawlowski on December 17th, 2010
@Outofscope You can play with my examples (http://web-desire.eu/lab/animation.html) there are 2 related with manipulation css from js. I’m pretty sure that using “-prefix-transform: translate” will be faster than any top/left coordinate which each time invoke reflow in browser.
I will add example with this today evening
Outofscope on December 17th, 2010
@Marek I came up with a simple technique to measure FPS in a browser: http://kon.stant.in/fps.html
Description: white blocks are moving with different speed, increasing top-down. The first block row number (counting top-down, starting from 1), where the blocks are near to immovable, shows the current number of FPS. E.g. on my iPhone the 11-th (as well as 2*11 = 22-th) row jumps from left to right, while others are moving in a certain direction. So, iPhone shows near 11 FPS.
This measurement can only be applied to the current scene: if I add a shadow to the blocks, the frame rate falls to 7 FPS on the same device.
Paul on December 17th, 2010
@Marek @Outofscope while animating the background position, you still get a huge performance increase if you set translate3d on the actual element you’re animating, as this will switch the compositing from software to hardware (GPU). I went from 4 fps in a game scene on iPad (with 15 animations) to 30 fps. How do I retrieve those numbers, you ask? Well..I have to use my best guess..when working with animations so long, you get a certain feeling for fps.
The Sea of Ideas » Finally: Sprite animations implemented via CSS3 Animations on December 15th, 2010
[...] animations implemented via CSS3 Animations Update: A way more awesome update with more techniques: Click me! Warning: This is hackier and more dirty than anything I have published in recent years, and only [...]