Let Physics Handle It
Go Down Deep Enough Into Anything And You Will Find Mathematics
Curves vs Maths
A curve, underneath, is a fixed path. You pick a start, an end, and a duration, and the animation walks from one to the other along a shape you drew ahead of time. Break it down and it is really just a timeline playing out: pre-set values, followed on a schedule, the same way every single time.
So I lean toward physics and maths instead, to make things feel more natural, even a little more human. Almost everything you can see can be written as an equation and simulated. Drop real-world physics into an interaction and it stops feeling scripted. You take the equation, hand it a few values, and run it, solved every frame or kicked off once per interaction, whatever the moment needs. That is the whole shift: from playing back a curve to letting a bit of physics work the motion out.
The Issue with Curves
The first thing you feel with a curve is that it is mechanical. It plays the exact same way every time, on rails, and after a few runs your eye starts catching the repeat. It is precise, but precise like a machine, not like something that is actually moving.
I am not against curves. For plenty of interactions they are the right call. A one-shot transition, a button pressing in, a sheet that opens once and closes once, none of that needs physics, and a well-shaped curve handles it cleanly. Reaching for a simulation there would just be overkill. Curves earn their place.
The trouble shows up the moment a gesture enters the picture. A curve is mostly uninterruptible, and it cannot be redirected mid-flight. Once it starts, it is committed to finishing the exact path it was handed, at the exact pace it was handed. So when the user grabs the thing halfway, or flicks it back the other way, the curve either ignores them and finishes anyway, or snaps and restarts. Both read as broken. The motion stops belonging to the finger, and that is where the experience quietly falls apart.
Why It's Better Than Curves
So here is what you get back. Physics moves the way real things move. A spring does not slide along a pre-drawn path, it gathers speed, overshoots a little, and settles, and your eye reads all of that as natural without anyone having to explain why.
It can do that because it was never a fixed set of values to begin with. There is no locked timeline underneath. The motion is solved from state as it happens, so it can land wherever the moment asks it to.
That also gives me real control. Instead of dragging control points around on a curve and hoping it feels right, I turn a couple of honest knobs, stiffness and damping, and I can feel exactly what each one does. It is control I can reason about instead of guess at.
The best part is that the interaction stops being fixed and starts depending on the person using it. Take a flick. The harder you flick, the more velocity you hand the spring, and the farther it travels, because that starting velocity is just your intent turned into a number. A gentle flick barely moves it, a sharp one sends it flying. The motion reflects what you actually meant, not what someone decided ahead of time.
And since it is all live, it is interruptible and redirectable by default. Grab it mid-flight and it comes with you, carrying whatever velocity it already had. Nothing to ignore, nothing to snap back. The motion stays yours the whole way through.
Common Examples
Two places I lean on this the most are springs and rubber banding. Between them they cover a huge share of what I build, so they are worth walking through slowly.
A spring is the workhorse. At its heart it is target-seeking motion: the object is pulled toward where it should end up, and a damper bleeds off the energy so it does not overshoot forever. A pull, plus a brake. That is the whole idea.
You hand it the current position, the target, and the current velocity, and you turn two knobs: stiffness (how hard it pulls) and damping (how much it resists). Every frame it solves a new position from those:
// one frame of a spring (mass = 1)
pull = -stiffness * (position - target) // Hooke's law, pull toward target
brake = -damping * velocity // resist the current motion
accel = pull + brake
velocity += accel * dt
position += velocity * dtThe feel lives in one number, the damping ratio. Low, and it overshoots and bounces before it settles. Just right, and it glides in and stops clean. High, and it crawls in slowly with no bounce at all. And because the object starts with whatever velocity the gesture gave it, a hard flick overshoots further than a gentle one, with no extra work from me.
Rubber banding is the soft wall you feel when you drag a list past its top. The content keeps following your finger, but less and less the farther you pull, so it feels like stretching against a band. Let go and a spring snaps it back to the edge.
It comes down to one small formula. Take how far past the edge you have dragged, the size of the view, and a resistance constant of about 0.55, and the real offset is:
// x = distance dragged past the edge
// d = size of the view (e.g. its height)
// c = resistance constant (~0.55)
offset = (c * d * x) / (d + c * x)Near the edge it follows almost one to one, so the start still feels responsive. But the farther you pull, the more the offset flattens out, approaching the size of the view and never passing it. That limit is the whole trick: no matter how hard you yank, the content never runs away, and the resistance in your fingers is just the maths quietly holding it back.