Motion
Motion explains, then stops: short, open to interruption, never looping without an end, and still when the phone asks for less motion.
Motion explains, then stops
#Motion in Patepang explains something, then stops. It is short, it can be cut off when the person moves on, it never loops without an end, and it is still when the phone asks for less motion.
Interface motion takes 300 ms at most. Something leaves about a fifth faster than it came, and nothing starts slowly: every curve begins at speed.
The sites keep even less: a quiet arrival as a page is scrolled, the browser’s own transition between pages, and two worked pieces on the front page of patepang.com.
Three curves
#Three curves, each with one job.
out(0.23, 1, 0.32, 1)Arriving, leaving, answering a press. The default, and the sites’ curve for almost everything.inOut(0.77, 0, 0.175, 1)Something moving from one place on the screen to another.sheet(0.32, 0.72, 0, 1)Dialogs and sheets.out · 220 msinOut · 240 mssheet · 300 msKinds and durations
#Every motion in the app is one of these kinds. A new animation picks a kind; it never brings a duration of its own.
| Kind | ms | In full | When less motion is asked for |
|---|---|---|---|
press | 120 | Ease-out; a button shrinks to 0.97, a round icon button to 0.92 | At once, the ground’s color only |
selection | 160 | Ease-out: a switch’s thumb, a check, a radio’s dot | At once |
enter / exit | 220 / 180 | Ease-out; rises 8 and fades in, and leaves faster than it came | A fade of 120 ms, nothing moves |
move | 240 | Ease-in-out: the indicator of a segmented control, a step filling | At once |
overlayEnter / overlayExit | 300 / 240 | The sheet curve; a dialog grows from 0.96, a sheet rises from below | A fade of 120 ms |
pulse | 900 | Per half cycle while something loads, eight cycles at most | Still |
stagger | 40 | Between one row of a list and the next, six rows at most | None |
Nothing travels far. What arrives rises 8 and no more; a dialog grows from 0.96, never from nothing; a mark of confirmation pops from 0.9.
Springs are kept for the moment a finger hands over its speed, a drag or a flick. Everything else is a curve with a duration.
When less motion is asked for
#The app follows the phone’s setting, also when it changes while the app is open. Then nothing slides, grows, turns or loops: a press and a choice answer at once, and what arrives or leaves fades for 120 ms.
The sites follow the browser’s setting: no arrival, no transition, nothing that runs. What was drawn by motion shows its final state.
What moves by itself
#A few things move by themselves, and each one is bounded.
| What | Its limit |
|---|---|
| The pulse of something loading | Eight cycles of 900 ms a half, then still |
| The three dots of someone typing | Six short waves; a new signal starts them again |
| The band of facts on patepang.com | A pause button beside it, and it rests under a pointer |
| The preview of a tempel | Once for each press |
The wordmark has a motion of its own, 300 ms from first to last: its two pa slide in, the te appears between them, and the panyecek rises last. It is set out on the Logo page.
Rules
#Do
- Move something only to say where it came from, where it went, or that a press was felt.
- Let a person interrupt it: what is tapped during a motion answers.
- Play a piece of motion once for each press.
- Give anything that runs by itself a way to pause it.
Do not
- Loop without an end.
- Start slowly: no ease-in at the start of a motion.
- Blur or scale what arrives on a page of a site.
- Move to draw the eye to something the person did not ask for.
In code
#In code the kinds and the curves have names, and the policy for less motion comes with them.
/* patepang.com */
transition: transform 220ms var(--ease);
@media (prefers-reduced-motion: reduce) {
transition: none;
}
// the app: a kind, never a raw duration
const spec = useMotionSpec('enter');
opacity.set(withTiming(1, timing(spec)));