How do I make translation transforms feel more natural?
An object undergoes a translation transformation when it moves from one point to another (it could rotate or grow or shrink in the process, but we’re going to concentrate here on the moving, or the translation).
This box below is translating from left to right in a linear fashion, i.e. it moves at a constant speed with an infinite acceleration at the beginning and end:
Do you notice how unnatural and mechanical it feels? Humans don’t move like that. It feels like the box is being moved by a robot, or like the box weighs less than air.
The problem here is that the box’s velocity is changing too quickly; i.e. its acceleration is too high. We can guess, then, that in order for the box’s position to change smoothly, its acceleration must stay as low as possible.
This box below translates with a constant and finite acceleration that switches sign at the halfway point (where it stops speeding up and starts slowing down). This kind of motion is called quadratic motion:
This certainly feels better! Play around with it a little, though. Does it seem to you that the box still moves a little… oddly? To me, it still looks like the box is being moved by a machine, like it’s missing a little human touch.
It turns out that minimizing acceleration isn’t enough. When humans translate (e.g. in a car on a smooth road with their eyes closed), they can’t sense either position or velocity at all. Translating in a car feels the same whether you’re in Minneapolis or Munich, or whether you’re moving at 10 m/s or 40 m/s.
What humans can sense when they move are the forces on their bodies, or, thanks to Newton’s Second Law, their acceleration. When our box moves quadratically, its acceleration jumps between zero and a non-zero value whenever it starts and stops. For truly natural movement, this acceleration has to look smooth as well.
Since we minimized acceleration in order to smooth out a changing position, and since acceleration is the second time-derivative of position, it’s a reasonable guess to try and smooth out a changing acceleration by minimizing the second time-derivative of acceleration[1]. This value is called snap (and it’s also the fourth time-derivative of position).
This box translates with a constant and finite snap that switches sign at the halfway point. This kind of motion is called quartic motion:
There! Now it feels like the box has some weight to it, like it’s being moved around by an actual person.
Effecting this in CSS is rather simple. transition-timing-function
has some default settings, such as ease-in-out
, but none of them quite cut it; we’ll have to use cubic bézier curves. Even though it’s impossible to create a perfect quartic curve with just cubic bézier curves, I’ve found the following to be an acceptable approximation[2]:
transition-timing-function: cubic-bezier(0.77, 0, 0.175, 1);
And that’s it; that one little line of code is all it takes to add a human touch to your motion animations.
- Wiegner, AW, and MM Wierzbicka. “Kinematic models and human elbow flexion movements: quantitative analysis.” Experimental Brain Research, vol. 88, no. 3, 1992, pp. 665–673.
- Sitnik, Andrey. “Easings Cheat Sheet.” “https://easings.net/de#easeInOutQuart”