Expand description
Animation kit — a named motion catalog as reusable helpers over gpui
Animation/AnimationExt.
Catalog (docs/research/feature-inventory.md §1.12):
fade-in0.5s cubic-bezier(0.16,1,0.3,1), translateY 4→0 (entrances)fade-quick0.15smenu-in0.14s scale 0.96 + translateY −2 (popovers)dialog-in0.18s scale 0.96→1splash-out0.5s opacity + translateY −6, 0.15s delaypulse2.4s staggered cell opacity 0.08→1, scale 0.9→1 (loaders)gradient-spin-pulse750ms per-cell phase wave (working indicator)- 200ms ease-out width/height transitions (sidebar/panes)
Custom easing is a closure over gpui’s Fn(f32) -> f32 easing shape; CSS
cubic-bezier() is evaluated exactly by CubicBezier.
Reduced motion: gpui’s App::reduce_motion flag is honored automatically by
every with_animation element — oneshot animations snap to their end state,
repeating ones to their start state, and no frames are scheduled.
AppExt carries that switch and the rest of the app-level settings; pure
helpers take the flag explicitly where they run outside elements.
translateY is implemented as a relative-position top inset: taffy applies
relative insets after layout, so — like a CSS transform — siblings never move.
gpui has no scale transform for divs at the pinned rev (only svg
transformations), so menu-in/dialog-in approximate their scale component
with fade + translate.
Re-exports§
pub use crate::phase::ORB_BLOOM_RINGS;pub use crate::phase::ORB_RING_DOT;pub use crate::phase::ORB_RING_DOTS;pub use crate::phase::ORB_RING_RADIUS;pub use crate::phase::ORB_SEATS;pub use crate::phase::ORBS;pub use crate::phase::PULSE_MIN_OPACITY;pub use crate::phase::PULSE_MIN_SCALE;pub use crate::phase::PULSE_STAGGER;pub use crate::phase::gspin_opacity;pub use crate::phase::orb_bloom_opacity;pub use crate::phase::orb_bloom_radius;pub use crate::phase::orb_converge_radius;pub use crate::phase::orb_drift;pub use crate::phase::orb_glow;pub use crate::phase::orb_opacity;pub use crate::phase::orb_ring_seat;pub use crate::phase::orb_size;pub use crate::phase::pulse_opacity;pub use crate::phase::pulse_scale;pub use crate::phase::pulse_wave;pub use crate::phase::staggered_phase;
Modules§
- phase
- Loader math — the pure phase functions behind the loading indicators.
Structs§
- Cubic
Bezier - A CSS
cubic-bezier(x1, y1, x2, y2)timing function (endpoints fixed at (0,0) and (1,1)). Evaluation solves x(t) = input by Newton iteration with a bisection fallback — the standard UnitBezier approach. - Fade
- Which fade: the view that paints it, and which element inside that view.
- Fade
Entry - One element’s hover fade: progress runs
origin → targetoverHOVER_FADE, re-anchored atoriginwhenever the pointer flips direction mid-flight so the blend is continuous. - Hover
Fades - Per-fade progress store. Pure core (explicit
now) — unit-testable; the thread-local wrappers below feed it the clock. - Motion
Spec - One catalog entry: duration + optional delay + curve. The delay is folded into
the gpui animation timeline (gpui
Animationhas no native delay): the animation runs fordelay + durationandprogressholds 0 until the delay has elapsed. - Painter
- A component’s line back to the view that paints it.
Constants§
- CHEVRON
- Diff-pane chevron rotate: 200ms (§1.11; approximated as a crossfade — gpui divs have no rotation transform at the pinned rev, same caveat as scale).
- COLLAPSE
- Diff-pane per-file collapse: 180ms height (§1.11).
- DIALOG_
IN - Dialog-in: 0.18s (scale 0.96→1 approximated).
- EASE
- CSS
ease— quick fades, menu/dialog pops. - EASE_
IN_ OUT - CSS
ease-in-out— the transcript scroll glide (browser smooth-scroll shape: gentle start, cruise, gentle landing). - EASE_
OUT - CSS
ease-out— width/height transitions. - EASE_
OUT_ EXPO - The signature entrance curve — CSS
cubic-bezier(0.16, 1, 0.3, 1). - EASE_
RESORT - Sidebar resort glide — CSS
cubic-bezier(0.22, 1, 0.36, 1)(used from M3b). - EASE_
TAILWIND - Tailwind’s default transition curve — CSS
cubic-bezier(0.4, 0, 0.2, 1)(transition-colorset al. carry it unless overridden). - FADE_IN
- Entrances: 0.5s expo-out fade + 4px rise.
- FADE_
QUICK - Quick fade: 0.15s.
- GRADIENT_
SPIN - Gradient matrix spinner wave period: 750ms.
- HOVER_
FADE - CSS
transition-colorsdefault: 150ms overEASE_TAILWIND— the temporal blend every interactive hover wash rides in the original. - MENU_IN
- Popover-in: 0.14s (scale 0.96 approximated, translateY −2).
- MENU_
OUT - Popover-out: 0.1s — quicker than the entrance (exits should get out of the way; matches the Radix convention of a shorter close than open).
- ORB
- Orb cluster breath: 2s, and
EASE_IN_OUTbecause a breath has no edges — the two spinners tick, this one swells. - PULSE
- Pulse loader period: 2.4s.
- RESIZE
- Sidebar / pane width+height transitions: 200ms ease-out.
- SCROLL_
GLIDE - Rail-tick / scroll-to-row glide: 500ms ease-in-out over the whole distance (Electron parity — the original rail rode the browser’s native smooth scroll, a fixed-duration gentle ease, never percent-of-remaining).
- SPLASH_
OUT - Boot splash exit: 0.5s fade + 6px lift after a 0.15s hold.
- TAB_
SLIDE - Terminal tab drag-reorder sliding transforms: 150ms (§1.10).
Traits§
- Animation
Ext - What the catalog’s one-shot entrances are built on. Repeats belong on
pulse_delta, which leases the view instead of pinning the window. An extension trait for adding the animation wrapper to both Elements and Components - AppExt
- The motion settings an app carries.
Functions§
- dialog_
in - Dialog entrance over
DIALOG_IN(scale approximated with fade + 2px rise). - fade_in
- Standard entrance: opacity 0→1 + translateY 4→0 over
FADE_IN. - fade_
quick - Quick opacity-only fade over
FADE_QUICK. - hover_
blend - The standard hover blend: rest → hover color at this fade’s progress.
- hover_
listener - An
.on_hoverlistener driving the fade — pair withhover_torhover_blendreads of the sameFadein the same element. - hover_t
- Hover progress (0..1) for
fadethis frame. - lerp
- Linear interpolation (layout tweens).
- matrix_
wave - Gradient-matrix spinner wave: intensity (0..1) of cell
wave_indexout ofwave_countdiagonals, at raw deltaraw_deltaof the 750ms period. The wave front travels across diagonals once per period. - menu_in
- Popover entrance: fade + translateY −2→0 over
MENU_IN. (the original also scales 0.96→1; divs have no scale transform in gpui — approximated.) - menu_
out - Popover exit: the reverse of
menu_in— fade to 0 + translateY 0→−2 overMENU_OUT. Unlike the entrances, the eased progresstcomes from the caller (computed offbezel::popover::Popup’s closing instant at render time):with_animation’s element-id-keyed clock replays from 0 on remount (the hover-blend comment’s warning), and a replay mid-exit is a full-opacity flash. The wall-clock progress is monotonic by construction; the animation wrapper here only pumps frames for the exit’s span, its own delta unused. - mix
- Blend two colors by
tthe way the browser transitions them: component interpolation in sRGB with premultiplied alpha — a wash fading in from transparent brightens without passing through grey. - pulse_
delta - Current phase
[0,1)of a repeating spec, plus a [lease] that keeps the calling view re-rendering at [PULSE_FPS] while its spinner stays mounted. All cells across all views share one epoch, so multi-instance loaders stay phase-locked. Reduced motion returns a static 0 and schedules nothing. - set_
hover - Record a hover flip for
fade(reduced motion snaps). Preferhover_listener, which also asks the clock for the frames to paint it. - set_
speed - Stretch every catalog timeline by
scale—10.0slows the 200ms pane tweens to 2s, so a screenshot burst can sample the geometry frame by frame. - speed_
scale - How far every timeline in the catalog is stretched.
1.0is the designed speed. - splash_
out - Boot-splash exit: hold 150ms, then fade out + lift 6px over 500ms.