Why Now? Why Me?
Lately we’ve been hearing a lot about adding personality and interest to apps with subtle animation, rather than with complex textures. As an animation guy from old times*, I couldn’t be happier about this new focus in iOS. There have always been lots of rich animation capabilities built into the frameworks, and based on nothing but the WWDC keynote, there’s bound to be even more simple, powerful animation API in iOS 7.
Of course, there’s still plenty that’s not easy. In the 2.5d world of iOS 7, things like SMShadowedLayer are more necessary than ever. Dimensionality is one way to add, if I may, depth to your animations. Another way is to infuse character and realism into the animated object.
Take a look at the principles of animation. Many of these – slow in and slow out, anticipation, timing – are provided by existing iOS animation APIs. More – arcs, follow through – are likely to be provided by iOS 7 APIs. But the most important item on the list, squash and stretch, is not addressed. This is a shame, as it’s a remarkably versatile technique. Used with a delicate touch, it can help the eye follow animation, making it easier to tell where an object is heading and at what rate. Used more liberally, it can add an appealing playfulness and character to the same animation.
I Fixed It For You.
SMSquashView and its backing class, SMSquashLayer, squash and stretch themselves automatically in response to motion. They will distort themselves longer in the direction of motion, and shorter in the perpendicular directions. The distortion is proportional to the velocity the object, and scaled such that its volume remains constant. In short: it does exactly what you’d want it to do, with no configuration required.
How Does It Work?
The math is pretty simple, if you like transformation matrices. Every time the layer’s position changes, we note the time and position delta from last time. Using that information we can calculate the velocity for the current frame of animation. We align a transformation matrix to the direction of travel using the same idea as gluLookAt, then scale according to the magnitude of the velocity.
Much the same as SMShadowedLayer, we won’t get enough information during implicit animations. Accordingly, we use exactly the same technique: set up a custom internal animatable property, tell the layer it needs to redraw when that property changes, but sneakily do our math rather than drawing when
display is called.
Where Can I Get It?
Here. There’s lots of really interesting open source code on our Github account, so you might want to check out the rest while you’re at it. This code in particular is short and quite well-commented (I think!) and might make a fun read.
*I argued for exactly this use of animation in my 2008 WWDC session. Prescient! I am willing to speak about the future of graphics and animation at your conference too, just ask.Tweet