Creating Animations and Interactions with Physical Models
by Ralph Thomas
8 November 2014

Physics-based animations and interactions are becoming more common in UI. This page goes through some basic physical models and the kinds of interactions and animations that can be constructed from them.

Scrolling on iOS is an excellent example of a physics-based interaction. When you drag your finger across the screen, the content tracks along with it, thereby scrolling, but when you lift your finger all of the physics magic happens: the content continues tracking with the same momentum and slows down under the influence of (virtual) friction. If you hit the end of the content, then the momentum goes into an overdamped spring which absorbs the momentum and returns you to the end of the content.

Everyone is familiar with scrolling, and all of the touch-based operating systems implement it because it feels so natural to use. But lets start with something a bit simpler: here are two buttons which get a bit smaller when you push down on them (to give visible feedback indicating that the UI has received your touch input). One of these buttons uses an underdamped spring to control its size, while the other uses more traditional CSS transitions.

Conserving momentum

In the button example above, the user input is a binary press (the button is either being pressed or not). In most of the other examples on this page, we'll instead seed the physics simulation with the current momentum and position of an object. To simplify the code, I always use a mass of 1, which means that velocity and momentum are the same number and thus interchangeable.

Why is it important to conserve momentum, though? What happens if we create animations that ignore the momentum that the user imparted to the UI?

This example is the UI for navigating back in Android Wear: you drag from the left to the right and release. One version ignores your momentum and just runs the same animation every time. The other example rolls the momentum into an constant acceleration (gravity) simulation if you drag with enough velocity or beyond the half-way point. If you don't drag far enough or drag in the other direction then a spring is used to take the menu back to where it started.

Recent research suggests we have an understanding of conservation of momentum from birth. I believe that UI which upholds these strongly held expectations is more pleasing than UI that ignores them.

Different simulations

We're going to look at three simple simulations: springs, constant acceleration (or gravity) and friction. These sound pretty boring, but combined with touch we can come up with some good interactions.

In this example we're using gravity to create a lock screen like the one in Windows 8. When you drag up on the image and release, it keeps its momentum but is pulled down by a constant acceleration. If you don't give it enough momentum, then it falls back down and the machine stays locked. This is a physics-based variant of slide-to-unlock.

Now we're going to compare constant deceleration (which is almost the same as the gravity example above; it just means the acceleration constant is negative) with friction. When I first started learning about physics simulations I thought that the constant deceleration simulation was the only way to slow things down and used it for everything, including scrolling. The result was terrible! My scrolling content would stop too abruptly and have a bad feel compared to everyone else's. For scrolling, as well as sliders, friction is a much better feeling simulation.

One way to think of the difference between deceleration and friction is to visualize the way an object slows down when you throw it up into the air before it starts falling again (this is constant deceleration) and the way an object slows down after it's been pushed along a table like an air-hockey puck when the table is off (friction). For the mathematically inclined, constant deceleration is a quadratic function of time whereas friction is a power function where time is the exponent.

In this example you can see the difference between constant deceleration and friction. Give each of the sliders a short, slow fling and watch how they slow down.

Combining simulations

So far we've used individual simulations (spring, gravity and friction) to create various interactions and animations. We can actually combine them to create even more interesting systems. In my recent game for Android, Letterplex, I made the dialogs fall from the top of the screen and land in the middle (as they do in the iOS inspiration Letterpress). However when they reach the middle of the screen, they bounce slightly as if landing on a cloud (or an overdamped spring).

In this non-interactive example you can see how the combination of gravity and a spring makes a nice feeling animation. Hit "Reset Position" to start the animation over.

Perhaps the most significant combination is friction with a spring to create scrolling. You've certainly seen this before, but try changing the coefficient of friction and the spring constants to better understand the kinds of systems you can create with these simple primitives.

Once you understand how something like scrolling is constructed, it's easy to make things like the "infinite" linear scroller in iTunes Radio on iOS 7. Here we have a constant velocity giving us a linear animation. Note: If you think you might ever drop a frame, don't use linear translation animations. Humans are amazing at tracking linear motion, so dropped frames will be perceived as very jarring. In contrast, humans seem bad at tracking things zooming in or out, so you can drop all kinds of frames in a zoom animation and most people won't notice.

This example uses a tweaked friction simulation that has a constant velocity which can be temporarily overcome by flicking left or right. Notice what happens when your imparted momentum is consumed and the scroller resumes its previous motion. It's smooth and seamless.

Mapping inputs and outputs

So far we've used press and velocity as inputs, and we've mapped the output of the physics simulation to either the translation or scale of the object. Our devices have a bunch of sensors and we can control more than just the initial velocity.

Here's an example where (on mobile only) we use the gyroscope to control the velocity to pan around in a photo. This is similar to Facebook Paper's photo viewer, but Facebook Paper uses a direct relationship between the gyro and the scroll position.

Note that this example only works on devices with gyroscopes.

We can also trigger springs based on proximity. I wrote up this example previously. Each face circle has a spring which is triggered when the cursor gets close. The motion of the face is then controlled by both the spring and the cursor position: the spring controls how far the face should be between its natural home position and where the cursor currently is.

Phew! Here's an example of mapping the output of a physics system differently. It's the "falling dialog" example from above, except that instead of translating the dialog downwards when it hits the ground, we squish it. Non-uniform scales don't usually look very pleasing, so it's hard to find any examples like this in real products.

Adding extra effects

Sometimes you've got a good looking animation or interaction, but you want to add something extra to it that is non-physical. Here's an example of adding a rotation to the falling dialog to make it look less one-dimensional. The question and answer app Jelly uses this to good effect when animating the question cards.

Conclusion

What did we learn?

I made a lot of mistakes and rewrote a couple of examples while writing this article (read my mistakes in the commit log). What did I learn?

The commented JavaScript source code to all of the above examples is available on github. Also check out Gravitas, a Java library I wrote which contains many of the physical models used here.

About the author
Ralph Thomas is a former high-school physics student who has spent the past 15 years focused on user interface implementation. A "full-stack" client engineer, Ralph has written high-performance mobile UIs from kernel input drivers, through OpenGL ES-based 2D graphics engines, physics engines and user interface toolkits up to full applications built on those foundations. Ralph has also contributed performance enhancements to the WebKit project. Follow Ralph on Twitter or send him email.