Skip to main content

Crate motion

Crate motion 

Source
Expand description

Animation kit — a named motion catalog as reusable helpers over gpui Animation/AnimationExt.

Catalog (docs/research/feature-inventory.md §1.12):

  • fade-in 0.5s cubic-bezier(0.16,1,0.3,1), translateY 4→0 (entrances)
  • fade-quick 0.15s
  • menu-in 0.14s scale 0.96 + translateY −2 (popovers)
  • dialog-in 0.18s scale 0.96→1
  • splash-out 0.5s opacity + translateY −6, 0.15s delay
  • pulse 2.4s staggered cell opacity 0.08→1, scale 0.9→1 (loaders)
  • gradient-spin-pulse 750ms 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§

CubicBezier
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.
FadeEntry
One element’s hover fade: progress runs origin → target over HOVER_FADE, re-anchored at origin whenever the pointer flips direction mid-flight so the blend is continuous.
HoverFades
Per-fade progress store. Pure core (explicit now) — unit-testable; the thread-local wrappers below feed it the clock.
MotionSpec
One catalog entry: duration + optional delay + curve. The delay is folded into the gpui animation timeline (gpui Animation has no native delay): the animation runs for delay + duration and progress holds 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-colors et 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-colors default: 150ms over EASE_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_OUT because 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§

AnimationExt
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_hover listener driving the fade — pair with hover_t or hover_blend reads of the same Fade in the same element.
hover_t
Hover progress (0..1) for fade this frame.
lerp
Linear interpolation (layout tweens).
matrix_wave
Gradient-matrix spinner wave: intensity (0..1) of cell wave_index out of wave_count diagonals, at raw delta raw_delta of 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 over MENU_OUT. Unlike the entrances, the eased progress t comes from the caller (computed off bezel::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 t the 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). Prefer hover_listener, which also asks the clock for the frames to paint it.
set_speed
Stretch every catalog timeline by scale10.0 slows 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.0 is the designed speed.
splash_out
Boot-splash exit: hold 150ms, then fade out + lift 6px over 500ms.