# Motion model

> How interanimate moves values — springs-first, with decay and tweens — described in perceptual terms.

This page defines the three kinds of **motion** — spring, decay, and tween — and the rules for choosing, parameterizing, interrupting, and completing them.

## Why springs first [#why-springs-first]

interanimate is springs-first because springs are the only common animation type that satisfies the **Continue** pillar on their own:

- **They start from anywhere.** A spring needs only a current value, a current velocity, and a target. It has no "start" that can be in the wrong place.
- **They can be retargeted at any instant.** New input changes the target; the motion bends toward it without a seam.
- **They absorb velocity.** A spring can begin with the exact velocity a finger left behind, so there's no visible join between dragging and animating.
- **They end gracefully.** A critically damped spring decelerates smoothly into its target instead of halting abruptly the way some fixed curves do when interrupted.

Springs are not about bounce. Most springs in interanimate have none. Apple's platforms use non-bouncy springs throughout and treat a zero-bounce spring as the versatile default; interanimate does the same.

Fixed-duration curves still have a place. Opacity and color have no momentum — nothing about a fade benefits from physics — and scripted, non-interactive sequences sometimes need exact timing. That's what tweens are for.

## Spring [#spring]

### Parameters [#parameters]

At the top layers, a spring is described by two perceptual parameters, following the model Apple adopted across its frameworks:

- **Duration** (perceptual) — roughly how long the motion feels like it takes. Higher is slower. In interanimate this comes from the [tempo](/docs/tokens#tempo) token.
- **Bounce** — how much it overshoots. `0` is critically damped: smooth, no overshoot. Positive values overshoot and oscillate. Negative values are overdamped: flatter, slower to arrive. In interanimate this comes from the [character](/docs/tokens#character) token.

Physical constants (mass, stiffness, damping) are derived from these and are only exposed at the lowest layer. Two parameters that mean something to a designer are better than three that mean something to a physicist.

### Perceptual duration vs. settling [#perceptual-duration-vs-settling]

A spring has no fixed end time. Its oscillations shrink toward zero but technically never stop. interanimate distinguishes two moments:

- **Perceptually complete** — the motion *looks* done. This is when follow-up UI may react (enable a control, move focus, start the next choreographed step).
- **Settled** — the value is within a negligible threshold of its target and velocity is effectively zero. This is when the motion releases ownership and resources.

Apple makes the same distinction and warns against waiting on full settling for anything user-facing. In interanimate: **nothing a person waits on is ever tied to settling.**

### Rules *(normative)* [#rules-normative]

1. Spatial channels use springs by default.
2. A spring always starts from the value's presentation value and current velocity.
3. Retargeting a spring never resets its velocity.
4. Default bounce is `0`. Positive bounce requires either momentum hand-off from an interaction or a `rare` frequency tier (Principle 10).
5. Bounce is capped below the range where it reads as exaggerated for UI.
6. Multi-dimensional spatial values (e.g. 2D position) are sprung per axis, so each axis keeps its own velocity.
7. Different properties of one element may finish at different times. This is expected and correct — it's part of what makes spring-driven motion feel natural.

## Decay [#decay]

**Decay** coasts a value from its current velocity toward rest, slowing continuously, with no target. It's the motion of a flicked list or a thrown card before it settles.

Decay has one perceptual parameter, **friction** — how quickly it slows. Low friction feels like ice; high friction feels like carpet.

Decay's most important role isn't as a visible motion; it's as a **prediction**. Given a release velocity and a friction, decay determines where something *would* come to rest if left alone. This is **projection** (see below).

### Rules *(normative)* [#rules-normative-1]

1. Decay begins only from an interaction hand-off with non-trivial velocity.
2. If decay would carry a value past a boundary, it hands off to a spring at the boundary, carrying its velocity (which may produce an earned overshoot).
3. If the value has discrete resting places (snap points), decay is used for projection only; the visible motion is a spring to the chosen snap point.

## Tween [#tween]

A **tween** moves a value along a fixed easing curve over a fixed duration.

### When to use a tween [#when-to-use-a-tween]

- **Effect channels** — opacity, color, blur, shadow. This is the default.
- **Scripted sequences** — non-interactive moments that need exact timing, such as a multi-step onboarding illustration.
- **Platform-native targets** — when a motion will be rendered by a native mechanism that only speaks in durations and curves.

### Easing [#easing]

interanimate does not ship a large menu of curves. It ships a small set of **roles**:

| Role | Shape | Use |
|---|---|---|
| **Enter** | Fast start, gentle arrival (ease-out family) | Things appearing or arriving |
| **Exit** | Same ease-out family as Enter, always shorter; an accelerating curve is allowed only for elements leaving the viewport entirely | Things leaving, usually with a fade |
| **Move** | Gentle start and arrival (ease-in-out family) | On-screen change from one state to another |
| **Linear** | Constant rate | Progress tied to time or input; continuous loops |

Kowalski's guidance favors ease-out as the default and custom curves over the browser's built-in keywords; IBM Carbon and Material both define separate entrance, exit, and standard curves. interanimate sides with Kowalski where they differ: a slow start delays the first visible change, which makes an interface feel sluggish at exactly the moment someone is watching it respond. So ease-in is disallowed on anything entering or changing on screen, and accelerating curves are reserved for the one case Material and Carbon use them well — something leaving the view entirely, where only the departure matters.

### Rules *(normative)* [#rules-normative-2]

1. Effect channels use tweens by default.
2. A tween interrupted mid-flight starts its replacement from the current presentation value. If the replacement is a spring, it also receives the tween's current velocity.
3. Tweens are never used for spatial channels under active or recently released direct manipulation.

## Projection [#projection]

**Projection** answers the question: *where was that gesture heading?*

When an interaction ends with velocity, interanimate uses decay to compute a **projected rest point** — where the value would naturally come to rest. It then picks the destination from the projected point, not from the release point. A quick flick on a half-open sheet should close it even if it was released above the halfway line; a slow drag past the halfway line and back should not.

This idea — make a small input produce the large output it implied — comes directly from Apple's fluid-interface work, which recommends snapping to the target nearest where momentum would carry the gesture.

### Rules *(normative)* [#rules-normative-3]

1. Projection uses release velocity, not release position alone.
2. The chosen destination is the valid target nearest the projected rest point.
3. The motion to that destination is a spring that inherits release velocity.
4. Under reduced motion, projection still chooses the destination (that is the person's intent), but the motion to it uses the reduced substitution.

## Boundaries and resistance [#boundaries-and-resistance]

When a value is pushed past a natural limit — the top of a list, the closed position of a drawer — interanimate applies **resistance** (rubber-banding) rather than a hard stop. Displacement past the boundary is progressively reduced: the further you pull, the less it moves. On release, a spring returns it to the boundary.

Resistance tells the person "there's nothing more this way" without feeling broken. A hard stop feels like the interface froze; no resistance feels like the interface fell apart.

## Interruption summary [#interruption-summary]

| In flight | Interrupted by | What happens |
|---|---|---|
| Spring | New target | Same spring, new target, velocity preserved |
| Spring / Decay / Tween | Interaction starts | Interaction takes ownership immediately at presentation value |
| Decay | Boundary reached | Spring to boundary, velocity preserved |
| Tween | New target (effect channel) | New tween from presentation value |
| Tween | New target (spatial channel) | Spring from presentation value and velocity |
| Anything | Preference changes to reduced | Current motion completes perceptually fast; subsequent motion uses reduced substitution |
