Where the Interpolator Lives
Custom animations are created inside screenStyleInterpolator, where each screen returns the animated styles for its built-in layers and any styleId targets it owns.
TSX
Derived Helpers
The top-level helper props are derived from the current screen relationship:
TSX
Use the top-level progress value when the whole stack relationship should drive the animation. Use current.progress, previous?.progress, or next?.progress when one specific screen should drive it.
progress includes live gesture movement. Use current.transitionProgress when you need the committed transition or snap progress without the active gesture.
In practice:
current.progressanimates0 -> 1when the current screen enters and1 -> 0when it exits- top-level
progressis often0 -> 1for the focused entering screen - top-level
progressis often1 -> 2for the screen underneath while anextscreen is covering it - when that top screen dismisses, those values move back toward the settled state
Interpolator Props
| Prop | Meaning |
|---|---|
current | The screen whose options.screenStyleInterpolator is being evaluated |
previous | The screen immediately below current, when one exists |
next | The screen immediately above current, when one exists |
active | The transition driver: current when focused, otherwise next |
inactive | The non-driver: previous when focused, otherwise current |
progress | Derived helper from current.progress + (next?.progress ?? 0) |
stackProgress | Accumulated progress from this screen upward through the stack |
focused | true when there is no next screen above current |
bounds | Bounds accessor for shared-element and navigation zoom helpers |
insets | Safe-area insets |
layouts | Layout measurements for the current screen |
Each screen state object contains the same fields:
| Field | Meaning |
|---|---|
progress | This screen's own progress value |
transitionProgress | This screen's transition or snap progress without live gesture movement |
closing | 1 while this screen is dismissing |
entering | 1 while this screen is opening |
willAnimate | One-frame pre-animation handoff signal |
animating | 1 while animation or gesture motion is active |
settled | 1 when the screen is idle and not dismissing |
gesture | Live gesture values for this screen |
meta | The value from options.meta |
options | Runtime transition options after base screen options and interpolator overrides are resolved |
route | The route object for this screen |
layouts.screen | Screen container size |
layouts.content | Measured content size when available |
layouts.scroll | Metadata from transition-aware scrollables |
animatedSnapIndex | Live snap index during gestures and animations, including fractional values between detents |
snapIndex | Current target snap index, updated by mount, snapTo(), and gesture release |
Use current.animatedSnapIndex when the visual state should follow the user's finger. Use current.snapIndex when the visual state should follow the selected target detent.
logicallySettled still exists as a deprecated alias for settled. New code should read settled.
Gesture Values
Each screen state's gesture object includes live pan, pinch, rotation, and handoff values:
| Field | Meaning |
|---|---|
x, y | Live pan translation after gestureSensitivity |
normX, normY | Normalized pan translation after gestureSensitivity |
scale, normScale | Live pinch scale values after gestureSensitivity |
focalX, focalY | Pinch focal point in screen coordinates |
pinchOriginX, pinchOriginY | Screen-coordinate focal point captured when the pinch activates |
rotation | Two-finger rotation in radians |
raw | Physical pan, pinch, and rotation values before gestureSensitivity |
handoff | Release-time gesture snapshot for dismiss handoff animations |
active | The active gesture: a resolved pan direction, pinch-in, pinch-out, or null |
dragging, dismissing | Gesture state flags |
Prefer gesture.active for new code. The older pan-only gesture.direction field still exists for compatibility.
focalX and focalY can move with the fingers. Use pinchOriginX and pinchOriginY when a transform should stay anchored to the point where the pinch began.
Live gesture values reset after release. If the dismiss animation needs the last drag, pinch, velocity, focal point, pinch origin, or rotation values, read from gesture.handoff.
Scroll Metadata
Transition-aware scrollables publish scroll state on current.layouts.scroll:
TSX
For nested same-axis scrollables, the outermost scrollable owns that axis. Cross-axis nested scrollables can each publish their own axis.
Runtime Options From An Interpolator
screenStyleInterpolator can return a reserved options key alongside layer styles. These values are consumed by the transition runtime and stripped before style slots are applied.
TSX
Use this for values that must change per frame on the UI thread, such as dynamic gestureSensitivity. Use navigation.setOptions() for React-side option changes such as toggling gestureEnabled or switching gestureDirection while a screen stays mounted. Structural options such as navigationMaskEnabled and gestureTracking must stay on the static screen options.
Supported runtime option keys are:
gestureEnabledgestureDirectiongestureSensitivitygestureVelocityImpactgestureSnapVelocityImpactgestureReleaseVelocityScalegestureSnapLockedsheetScrollGestureBehaviorbackdropBehavior
Deprecated compatibility keys are still accepted:
gestureProgressModegestureDrivesProgressgestureActivationAreagestureResponseDistance
Returning Styles
Return built-in layer slots or any custom key that matches a styleId on a transition-aware component:
TSX
Reserved layer slots are:
contentbackdropsurface
Any other key is treated as a styleId target. Each slot accepts either shorthand style output or the explicit { style, props } form.
Return null, undefined, or {} when a frame should apply no transition styling.
Style Reset Behavior
The style resolver tracks the keys each slot emitted previously. When a later frame drops a transition-owned key, the library emits a concrete identity reset for that key so Reanimated does not keep stale animated values alive.
This applies to visual transition props such as transform, translateX, translateY, scale, opacity, zIndex, elevation, border radius/color, shadow props, backgroundColor, overflow, and pointerEvents.
Layout-owning props such as width, height, margin, padding, top, left, flex, and aspectRatio are not reset to zero. If you animate layout-owned props, keep returning the value while you need it, then let your own component styles own the settled layout.