Skip to content

Animation API

Declared by <huxerui/animation.h>.

  • Easing: Linear, EaseIn, EaseOut, or EaseInOut.
  • CubicBezierCurve(x1, y1, x2, y2): custom control points exposed by X1, Y1, X2, and Y2.
  • TimingCurve: variant of Easing or cubic Bézier.
  • SnapSpec: immediate target.
  • TweenSpec: duration and easing.
  • SpringSpec: stiffness and damping_ratio.
  • ProgressKeyframe: fraction, progress, and curve_to_next.
  • KeyframeSpec(duration, keyframes): validated ordered keyframes exposed by Duration() and Keyframes().
  • AnimationSpec: variant of all four spec kinds.
  • RepeatMode: Restart or Reverse.
  • AnimationPlayback: delay, optional iterations, and repeat_mode.
  • MotionAdvanceResult: progress and whether another frame is required.
  • MotionController: inspect Value, Target, Velocity, and IsRunning; change motion with Set, Seek, AnimateTo, and Advance.
  • Animated<T> couples target value, AnimationSpec, and playback.
  • AnimateTo(target, spec, playback = {}) constructs it.
  • Presentation properties: Opacity, Offset, Scale, and Rotation.
  • TransformOrigin controls scale/rotation origin.
  • Transition(progress) accepts a float or Animated<float> and adds Opacity(from, to), Offset(from, to), Scale(from, to, origin), and Rotation(from, to, origin) tracks.
  • TransitionSpec(effect, AnimationSpec, delay = 0) describes a one-shot effect. Built-ins are FadeTransition, SlideTransition, ScaleFadeTransition, and CircularRevealTransition.
  • SceneTransitionAnchor tags retained scene content and is obtained from SceneTransitionHandle::Anchor().
  • UseSceneTransition() -> SceneTransitionHandle; Run(TransitionSpec, mutation) applies a synchronous state mutation. RunAt(origin, spec, mutation) supplies a window-local logical origin; RunFromCurrentInteraction(spec, mutation) uses the current synchronous pointer position or the activated control’s center for keyboard/accessibility input. It does not require an Anchor and cannot be deferred beyond that interaction callback.

Navigation uses PageTransition from navigation.h with independent push/pop/replace TransitionSpec values. Presentation services retain their owning PresentationMotion contract; choosing a scene effect does not change Dialog or Popup layout.

TransitionContext contains progress, container-local logical bounds, and optional origin. Spring progress can overshoot 0–1; custom effects must return valid finite output even then. TransitionFrame contains outgoing and incoming TransitionSample values plus TransitionOrder (IncomingAbove or OutgoingAbove).

Each sample has a transform, opacity, optional post-transform clip, and optional fragments. A TransitionFragment selects a source_clip before its transform and opacity; fragments share the side’s common transform and final clip. Empty fragments draw the original content once; nonempty fragments replace that drawing and add no layout or input nodes.

Effect Configuration
FadeTransition Crossfade with clamped opacity.
SlideTransition incoming_offset and outgoing_offset are fractions of container dimensions, not DIPs.
ScaleFadeTransition incoming_scale (0.92), outgoing_scale (1), and TransformOrigin pivot.
CircularRevealTransition Requires context.origin; a page has no implicit origin. Supply one in a custom page effect or use a scene RunAt.

TransitionSpec requires a copyable, equality-comparable effect with TransitionFrame Evaluate(const TransitionContext&) const. Optional void Paint(PaintContext&, const TransitionContext&) const records decoration above both sides. Neither method may mutate application state, call hooks, advance time, or start another transition. Output validation rejects invalid geometry atomically; effect exceptions propagate.

Animation(), Delay(), IsImmediate(), Evaluate(), Paint(), and Reversed() inspect or sample the value. Reversed(animation) also replaces timing. Default specs finish immediately; repetition is unsupported and springs require positive damping. Runtime handles reduced motion. Specs share immutable effect data; they do not own mutable progress.

SharedElement(key) marks the same retained visual at two locations. SharedBounds(key) moves the bounds of different content while crossfading. Keys accept strings, integral values, or enums, preserving signed/unsigned alternatives. Pairing follows the active operation, not a global identifier registry.

NavigationStack matches marks between participating pages using the page operation’s progress, including predictive Back. For a local state change, obtain SharedTransitionHandle with UseSharedTransition, attach its Scope() modifier to one stable container, and invoke Run(animation, mutation). Only matched visuals animate; unmatched content immediately adopts the new layout. Input inside that local scope is disabled while motion runs.

Both marks accept BoundsTransform(effect): a copyable, equality-comparable value with Rect Evaluate(Rect from, Rect to, float progress) const. It must preserve endpoint rectangles exactly and keep geometry valid during overshoot. It changes retained drawing, not intermediate text wrapping or layout.

Missing, unrealized, partially ancestor-clipped, rotated/skewed, fragment-rendered, PlatformView and ExternalTexture content cannot be assumed to pair; normal drawing remains the fallback. Viewport/coordinate-space changes end an active local operation. A new Run starts from committed visuals, without a velocity-continuity guarantee. See the complete local example.

Concern Contract
Value ownership Curves, specs, playback, and presentation modifiers are copyable values. MotionController retains mutable playback state.
Validation Invalid Bézier control points, keyframe order, duration, spring parameters, or playback values throw std::invalid_argument at construction or start.
Frame time Call Advance(FrameInfo) with runtime frame time; do not advance from a detached timer.
Reduced motion Theme/runtime policy may resolve an animation to an immediate state. Application logic must not depend on intermediate frames.
Selection Use Animated<T> for one presentation property, Transition for coordinated properties, and scene transitions for a rendered before/after snapshot.