Skip to main content

gpui_kit/motion/
mod.rs

1//! Motion primitives that respect the user's reduced-motion preference.
2//!
3//! The layers build on each other:
4//!
5//! - [`CubicBezier`] and [`Easing`] name curves;
6//! - [`Spring`] solves physical motion in closed form;
7//! - [`MotionSpec`] pairs a curve with a duration and delay;
8//! - [`Interpolate`] moves a value between two states;
9//! - [`Keyframes`] takes a value through named stops rather than straight
10//!   across;
11//! - [`Transition`] animates a value whose target can change mid-flight,
12//!   carrying the speed it already had across a retarget;
13//! - [`VelocityTracker`] measures how fast a gesture is moving, which is what
14//!   [`flick`], [`rubber_band`] and [`Transition::release`] need;
15//! - [`ScrollLink`] reads a scroll offset as a progress, which is motion with
16//!   no clock in it at all;
17//! - [`Presence`] keeps an element alive long enough to animate out, and plays
18//!   a phase backwards from where it had got to when the other cancels it;
19//! - [`Stagger`] spreads one specification across a group, forwards or in
20//!   reverse;
21//! - [`Sequence`] runs specifications one after another and knows how long
22//!   they take together;
23//! - [`Flipping::flip`] slides an element from where it was to where it is,
24//!   and [`Flipping::flip_size`] additionally resizes it;
25//! - [`Animated::animate_in`] puts any of this on an element in one call,
26//!   which is the layer most components should reach for.
27//!
28//! Motion never changes what a surface publishes. A slide, a press response
29//! and a counting number are all painted over a layout, a hit target and a
30//! semantic tree that already report the settled value.
31//!
32//! Decorative motion built on GPUI's `with_animation` already stops when
33//! [`gpui::App::reduce_motion`] is set. [`Transition::animate`] and
34//! [`Presence::animate`] honor the same preference by finishing immediately.
35
36mod animated;
37mod busy;
38mod easing;
39mod flip;
40mod gesture;
41mod interpolate;
42pub(crate) mod keyed;
43mod keyframes;
44mod presence;
45mod scroll_link;
46mod sequence;
47mod spec;
48mod spring;
49mod stagger;
50mod transition;
51
52pub use animated::{Animated, Entrance};
53pub use busy::{Activity, breathe, breathing_dot, spin, sweep};
54pub use easing::{CubicBezier, Easing};
55pub use flip::{Flip, Flipped, Flipping, flip, shared_flip, tracked_ids};
56pub use gesture::{Flick, VELOCITY_WINDOW, Velocity, VelocityTracker, flick, rubber_band};
57pub use interpolate::Interpolate;
58pub use keyframes::{Keyframe, Keyframes};
59pub use presence::{Phase, Presence};
60pub use scroll_link::ScrollLink;
61pub use sequence::Sequence;
62pub use spec::{
63    MotionSpec, content_in, dialog, dialog_arrival, dialog_in, entrance, fade_in, gradient_opacity,
64    menu, menu_in, pulse_wave, resize, row_in, shimmer_offset, state_change, tracking,
65};
66pub use spring::Spring;
67pub use stagger::{ROW_STAGGER_CAP, Stagger, staggered_phase};
68pub use transition::Transition;
69pub(crate) use transition::{tracked, tracked_or_snap};
70
71pub use gpui::AnimationExt;
72
73/// Whether the user asked for non-essential motion to be suppressed.
74pub fn reduce_motion(cx: &gpui::App) -> bool {
75    cx.reduce_motion()
76}