Skip to main content

Module motion

Module motion 

Expand description

Tilo’s standard motions: the one library every animation in the toolkit, the shell and the apps is composed from. A call site says what moves, never how:

MotionFor
Appear / Appearing / Appearancepopovers, menus, dropdowns, tooltips, sheets, dialogs coming from their origin and going back
Drill / DrillDepthdrill-in and back inside a panel; whole-column pushes
Disclose / Extent / Disclosureexpand and collapse; a panel’s height following its content; a find bar or banner coming and going
PanelSlidesidebars, drawers, the inspector
CrossFadeswapping content in place
ListChangerows arriving, leaving and changing places
Snapcarousels and paged strips settling on a detent
ScrollToa scroll view going to what it was asked to show (find next, a revealed row)
Zoomone thing becoming another (window and overview card)
WindowMotionwindows opening, closing and moving on the strip
Ambientchrome that comes back on its own (desk widgets)
Transienta readout or acknowledgement that goes on its own
Followa peer’s pointer gliding between the samples it is heard at
Floata reaction rising from the pointer it was sent from
Tracea collaborator’s just-typed run fading on its own
Breathea live state’s soft ring (someone in a call)
Feedbackpress and hover tints
ControlChange / Thumb / Marka switch’s knob and tint, a checkbox’s mark, a slider’s thumb, a badge’s count
Attentiona refusal’s shake, a single pulse
Beckona control hint arriving, showing its gesture, and acknowledged

Every motion runs on MotionValue: a spring solved in closed form, so it is exact at any frame rate, retargets from where it is drawn and how fast it is moving there (interruptible, never a jump, never a queue), and is exactly at rest once within tolerance (a settled motion asks for no frames). Presence is the openness of anything that comes and goes. Each motion’s MotionSpec decides its pace in and out, what a shortcut gets (the result lands at once) and what reduced motion becomes (spatial movement lands; changes of what is shown still fade).

Rules every motion keeps (HIG.md §9.7): input never waits for a motion; routine motion never bounces; content is laid out once and moved by transform, clip and opacity; nothing moves under a pointer that is aiming at it (held_by_aim); a moving surface is hit-tested where it is drawn (Pose::to_local).

A motion that is genuinely new is added here, with its spec and pose, rather than written at its call site: tools/policy/check_motion_library.py rejects easing math, ad-hoc springs and lerp-over-time anywhere else.

Modules§

testing
The settled clock, for captures and tests.

Structs§

Ambient
Chrome that comes back on its own and goes when it would be in the way: desk widgets, the Super surface’s time card. Leaving is instant, since motion would draw the eye for nothing; arriving unasked is slow and opacity only; arriving asked for is fast.
Appear
A popover, menu, sheet or dialog coming from the control that summoned it and going back to it, both about the origin nearest that control; the constants below are its shares and reach.
Appearing
The coming and going of one surface on the standard Appear motion.
Arrival
How the card is drawn while it arrives and rests.
Attention
Calling the person’s eye: a refusal shakes (a wrong password), something that needs them pulses once; never loops.
Beckon
A control hint’s motion (crate::control_hints).
Breathe
A state that is live for as long as it lasts: the soft ring on the face of someone in a call. It breathes slowly, the only motion that loops, so it is reserved for something happening right now; where motion may not loop it holds at full.
Completion
How the card is drawn once its gesture was done.
ControlChange
A control showing its new value: a switch’s knob and tint, a checkbox’s fill and mark, a slider’s thumb, a badge’s count. Self::MOVE is where the moving part is (fast, critically damped); Self::SHOW is what the control shows for its state (fast, a fade under reduced motion too). Only a click or a finger moves a control; a key, an assistive action or a value the person did not just cause shows on the next frame.
CrossFade
Disclose
A disclosure, an accordion, a panel whose height follows its content: the clip height moves over content laid out once at its full height and fades in over the second half; open at base, close at fast, longer for tall reveals.
Disclosure
The coming and going of one band (a find bar, a banner) on the standard expand/collapse motion (Disclose): its clip height opens from the top and what follows it moves with the band’s edge, by transform.
Drill
Moving deeper into a panel and back: Quick Settings submenus, push navigation, settings sub-pages. Each page is posed by its offset from one continuous depth (DrillDepth).
DrillDepth
The drawn depth of a drill-in stack.
Extent
An extent that follows its content (a panel’s height when its page changes), on the expand/collapse motion.
Feedback
The pressed or hovered tint of a control: it comes at once (zero latency is the feedback) and goes over fast; list rows and menu items use the instant state, as hovering across a list is too frequent to leave trails.
Float
A reaction floating up from the pointer it was sent from: it rises, slowing as it goes, and fades over the second half of a fixed life, since the reaction is the content of that moment and has to be readable before it goes.
Follow
Something following a stream of samples it does not control (a peer’s pointer, heard about thirty times a second): between two samples it glides over the gap so it arrives as the next is due (Self::glide), and when the stream goes quiet it fades over the caller’s retirement window. It has no token: the pace is the data’s own.
HandOn
The hand-on of a widget its view may build anew on every change: the widget built in its place goes on from the motion this one leaves (keep), found by the identity it was given, else by its kind and place.
ListChange
Rows arriving, leaving and changing places: a survivor springs from its old place to its new one (base), arrivals and departures fade while their slots open and close (fast), driven by crate::collection_transition::RowMotions; a change that would move the row under an aiming pointer waits (held_by_aim).
Mark
What a control shows for its state, 0 off to 1 on (a switch’s tint, a checkbox’s fill and mark). It comes in over fast and goes quicker on ControlChange::SHOW, continuing from what is drawn mid-flight.
MotionSpec
The timing of one named motion.
MotionValue
A value following its target on a spring, in closed form.
PanelSlide
A sidebar, drawer or inspector sliding in from its edge. Content beside a docked panel is laid out at the wider of its two widths and slides with it, so it reflows once, never per frame (Self::content_width).
Placed
One surface’s arrival, departure and movement, sampled once per drawn frame.
Pose
An opacity and a transform (in the surface’s own coordinates, applied before the surface’s placement).
Presence
The openness (0..=1) of something that comes and goes, on the spring its named motion picks. The intent (Self::is_open) changes the moment it is asked for, so input acts on the new state at once; the openness only says how it is drawn.
Reveal
How much of a disclosed block shows.
RubberBand
The give of a scroll view past its ends, per axis: negative before the start, positive past the end, in logical pixels.
ScrollTo
A scroll view’s motion toward what it was asked to show.
Snap
A carousel or paged strip settling on a detent: the release projects the fling (Self::rest_for), picks the nearest detent and carries the release velocity into it (base, no bounce); a wheel notch retargets, so spins accumulate into one motion.
Speaking
A person’s voice on their face while they talk in a call: the ring is there the moment their voice is heard and eases out over fast when they pause, so it pulses with their speech.
SpringSpec
A spring’s shape: how quick (response) and how bouncy (damping).
Thumb
A control’s moving part (a switch’s knob, a slider’s thumb) as a share of its travel, 0..=1: a click sends it on ControlChange::MOVE, a second click mid-flight retargets from where it is drawn, the hand holds it exactly where it is (Self::track), and let go it settles carrying the hand’s velocity.
Trace
A mark a collaborator just left (the run a peer typed) going on its own: whole when made, it steps down evenly over Self::LIFE in Self::STEPS steps, each step a wake deadline, so a typing window repaints a few times a second rather than at every refresh.
Transient
Something shown for a while that then goes on its own: a volume readout, an acknowledgement, a player’s controls. A readout arrives at fast, a confirmation is there at once; both hold, then fade over base so they are gone exactly when they expire. Pure functions of two instants, so the owner keeps no motion state.
WindowMotion
Windows opening, closing, moving and resizing on the strip: rects spring on springs.heavy (critically damped, mass you can feel), longer for a long move; an opening window’s content fades in and scales 0.96 → 1 about its centre (slow); a drag is welded to the hand.
Zoom
One thing becoming another in place (a window and its overview card, a photo and its full view): one rect spring between the two (slow in, base out, longer across the screen) and the contents cross-fade over the middle half.

Enums§

Appearance
One Appearing a surface and the host that draws it share.
Direction
Which way a motion is going.
Feel
The pace a component’s motion plays at: Self::Standard is the theme’s, the others multiply the theme’s token durations, and Self::Still holds the component still.
Pace
A pace from the motion tokens.
Reduced
What a motion becomes under reduced motion.
ScrollJump
What ScrollTo::go did with a jump.
Shortcut
What a motion does when a shortcut or an action asked for it.
Timing
How a value goes to a new target.

Constants§

CROSS_FADE
Swapping one content for another in place (the bar’s clock and a live activity, an image over its placeholder): the old fades out over the first 60 %, the new in over the whole fast spring, nothing moves. Also the timing for a fade that carries no content of its own.

Traits§

Animatable
A value a motion can carry: a point, a rect, a colour, an amount.

Functions§

blend_across
A blend between two values as a layout’s size crosses a range, eased so it is flat at both ends: 0 at or below from, 1 at or above to, and a smoothstep between. A responsive change driven by width or height (a stage cross-fading between breakpoints) moves at the same shape a motion does, rather than snapping at the breakpoint.
frame_drawn
A frame was drawn reading its motions at at (taken before drawing, so every motion the frame read was at at or later). Every host that asks frames_wanted says so for each frame it draws, as the surface it draws for ([own]): the frame at rest after a motion ends is owed until one drawn at or after its end.
frame_laying_out
Whether a frame is being built, laid out or drawn on this thread. Work an app ran elsewhere that lands meanwhile (a device read on a thread of its own) is taken in by the next frame, which the work’s wake asks for: taken in now, it would compose the frame again partway through, at whatever pass it happened to land in.
frame_now
The instant a motion is read at: the frame’s, while its layout is pinned (pin_frame), else now. A widget that sizes itself by a motion (a disclosure opening) reads it here, so every layout pass of one frame sees the same pose and the frame’s composition can settle; read at the clock, each pass saw the motion a little further on and the passes never agreed.
frames_until
When the motions on this thread that still need frames have all settled; None when none does.
frames_wanted
Whether a motion on this thread still needs a frame at now: it is moving, or it has settled since the last frame was drawn and the frame showing it at rest is still owed. A frame read while a motion was a hair from its end leaves that last sliver on screen otherwise.
frames_wanted_by
Where the motions that still need frames at now asked for them (file:line of each caller), for diagnostics: the ones moving, and the ones whose frame at rest is still owed.
held_by_aim
Whether a motion that would move rect must wait: the pointer is aiming at it.
input_source
The input the toolkit handled last on this thread: what a surface that opens or closes now follows. A key opened it, so it lands at once; a click opened it, so it moves.
keep
Leave value, the motion state of a widget being dropped, for the widget a rebuild puts in its place: the one with the same id, or else one laid out where it was (at).
note_input
Note that event is being handled: what it opens or closes follows it (input_source). The window’s event entry points call this before dispatching, so every surface the toolkit shows knows what asked for it without each owner threading the source through.
note_source
Note that source is acting (an action door or agent performing a control is MotionSource::Action).
recent_input
The input a change happening at now follows, if the person just made one (a few hundred milliseconds ago): what a list uses to animate a row the person added or removed, and to leave one a sync added alone.
source_of
The input event comes from, for a host that opens and closes surfaces on later frames and needs to know what asked: None for events that are not input.
stage
The progress of a part of a motion running over from..to of the whole one’s progress, 0..=1; parts share its spring, so they stay in step when it is interrupted.
take_kept
What a widget of the same kind with this id left when a rebuild dropped it, if anything.
take_kept_at
What a widget of the same kind left when a rebuild dropped it from where this one is laid out (at: the same top left corner and width), if anything.
take_kept_where
What a widget of T’s kind left that matches, if anything.
unit_opacity
x clamped to 0..=1 as an opacity.
want_frames_until
A motion on this thread moves until until: the frame pump draws frames until then. The caller is remembered as the owner of those frames (frames_wanted_by), so a motion asking here is named while it moves.
window_has_shown
Whether the window being laid out has shown a frame before: a widget in its first frame shows at rest (first paint shows the resting state; motion explains changes).

Type Aliases§

Channels
Up to four channels moving together on one spring.