Skip to main content
ScreenInterpolationProps contains all the values you need to create custom screen animations. It’s passed to your screenStyleInterpolator function and provides access to progress values, screen states, layouts, and shared element bounds.

Type Definition

interface ScreenInterpolationProps {
  // Screen states
  previous: ScreenTransitionState | undefined;
  current: ScreenTransitionState;
  next: ScreenTransitionState | undefined;
  active: ScreenTransitionState;
  inactive: ScreenTransitionState | undefined;

  // Progress values
  progress: number;
  stackProgress: number;
  snapIndex: number;
  focused: boolean;

  // Layout and bounds
  layouts: { screen: Layout };
  insets: EdgeInsets;
  bounds: BoundsAccessor;

  // Deprecated
  isActiveTransitioning: boolean;
  isDismissing: boolean;
}

Screen States

Each screen in the stack has a state object containing animation values and metadata.
current
ScreenTransitionState
Values for the screen being interpolated.This is the screen you’re defining animations for.
previous
ScreenTransitionState | undefined
Values for the screen before the current one in the stack.undefined if current screen is the first screen.
next
ScreenTransitionState | undefined
Values for the screen after the current one in the stack.undefined if current screen is the topmost screen.
active
ScreenTransitionState
The screen state currently driving the transition.This is either current or next, whichever is focused.
inactive
ScreenTransitionState | undefined
The screen state NOT driving the transition.When focused, this is the previous screen. When not focused, this is the current screen.

ScreenTransitionState Properties

Each screen state contains these animated values:
progress
number
Animation progress for this screen.
  • 0 - Screen is fully off-screen (entering)
  • 1 - Screen is fully visible (active)
Animates from 0 to 1 when entering, and from 1 to 0 when exiting.
closing
number
Whether this screen is being dismissed.
  • 0 - Screen is opening or active
  • 1 - Screen is closing/being dismissed
Use this to trigger different animations when navigating back vs forward.
entering
number
Whether this screen is entering.
  • 0 - Screen is closing or inactive
  • 1 - Screen is opening/entering
Use this to trigger different animations when navigating back vs forward.
animating
number
Whether this screen is currently animating.
  • 0 - No animation in progress
  • 1 - Animation or gesture is in progress
gesture
GestureValues
Live gesture values for this screen.Properties:
  • isDragging (number) - Whether user’s finger is on screen (0 or 1)
  • x (number) - Horizontal translation in pixels
  • y (number) - Vertical translation in pixels
  • normalizedX (number) - Horizontal translation normalized (-1 to 1)
  • normalizedY (number) - Vertical translation normalized (-1 to 1)
  • isDismissing (number) - Whether screen is being dismissed (0 or 1)
  • direction (GestureDirection | null) - Initial direction that activated the gesture
meta
Record<string, unknown> | undefined
Custom metadata passed from screen options.Use for conditional animation logic instead of checking route names.
route
BaseStackRoute
The route object for this screen.Contains route name, params, and key.

Progress Values

progress
number
Combined progress of current and next screen transitions, ranging from 0-2.
  • 0 - Screen is entering (off-screen)
  • 1 - Screen is visible (active)
  • 2 - Screen is exiting (being covered by next screen)
stackProgress
number
Accumulated progress from the current screen’s position onwards in the stack.Unlike progress (0-2), this ranges from 0-N where N is the number of screens above the current screen. Each screen at index I sees stackProgress as the sum of all progress values from index I to the top of the stack.Falls back to progress when not in blank-stack.
snapIndex
number
Animated index of the current snap point.Interpolates between indices during gestures/animations.
  • Returns -1 if no snap points are defined
  • Returns 0 when at or below first snap point
  • Returns fractional values between snap points (e.g., 1.5 = halfway between snap 1 and 2)
  • Returns length-1 when at or above last snap point
focused
boolean
Whether the current screen is the focused (topmost) screen in the stack.Use this to apply different animations for the incoming vs outgoing screen.

Layout and Measurements

layouts
{ screen: Layout }
Layout measurements for the screen.Layout properties:
  • width (number) - Screen width in pixels
  • height (number) - Screen height in pixels
insets
EdgeInsets
Safe area insets for the screen.EdgeInsets properties:
  • top (number)
  • right (number)
  • bottom (number)
  • left (number)
bounds
BoundsAccessor
Function that provides access to bounds builders for shared element transitions.BoundsAccessor options:
  • id (string) - The sharedBoundTag to match
  • method (“transform” | “size” | “content”) - How to animate
  • space (“relative” | “absolute”) - Coordinate space
  • scaleMode (“match” | “none” | “uniform”) - Aspect ratio handling
  • raw (boolean) - Return raw values

Deprecated Properties

isActiveTransitioning
boolean
Deprecated: Use active.animating instead.
Whether the active screen is currently transitioning.
isDismissing
boolean
Deprecated: Use active.closing instead.
Whether the active screen is being dismissed/closed.

Complete Examples

Slide from Bottom

import { interpolate } from "react-native-reanimated";
import type { ScreenStyleInterpolator } from "react-native-screen-transitions";

const slideFromBottom: ScreenStyleInterpolator = ({
  progress,
  layouts: { screen },
}) => {
  "worklet";

  return {
    contentStyle: {
      transform: [{
        translateY: interpolate(progress, [0, 1], [screen.height, 0])
      }]
    },
    backdropStyle: {
      backgroundColor: "black",
      opacity: interpolate(progress, [0, 1], [0, 0.5])
    }
  };
};

Draggable Card with Scale

const draggableCard: ScreenStyleInterpolator = ({
  current,
  progress,
  layouts: { screen },
}) => {
  "worklet";

  const scale = interpolate(progress, [0, 1, 2], [0, 1, 0.75]);

  const translateY = interpolate(
    current.gesture.normalizedY,
    [-1, 1],
    [-screen.height * 0.5, screen.height * 0.5],
    "clamp"
  );

  const translateX = interpolate(
    current.gesture.normalizedX,
    [-1, 1],
    [-screen.width * 0.5, screen.width * 0.5],
    "clamp"
  );

  return {
    contentStyle: {
      transform: [
        { scale },
        { translateY },
        { translateX }
      ]
    }
  };
};

Conditional Animation with Meta

const conditionalAnimation: ScreenStyleInterpolator = ({
  progress,
  next,
  focused,
}) => {
  "worklet";

  // Only scale if next screen has scalesOthers meta
  const shouldScale = next?.meta?.scalesOthers === true;

  if (shouldScale && !focused) {
    return {
      contentStyle: {
        transform: [{
          scale: interpolate(progress, [1, 2], [1, 0.9])
        }]
      }
    };
  }

  return {
    contentStyle: {
      opacity: interpolate(progress, [0, 1], [0, 1])
    }
  };
};

Stack Depth Effect

const stackDepth: ScreenStyleInterpolator = ({ stackProgress }) => {
  "worklet";

  return {
    contentStyle: {
      transform: [
        {
          scale: interpolate(
            stackProgress,
            [0, 1, 2, 3],
            [1, 0.95, 0.9, 0.85]
          )
        },
        {
          translateY: interpolate(
            stackProgress,
            [0, 1, 2, 3],
            [0, -10, -20, -30]
          )
        }
      ],
      opacity: interpolate(
        stackProgress,
        [0, 1, 2, 3],
        [1, 0.9, 0.8, 0.7]
      )
    }
  };
};