Skip to main content
The DraggableCard preset creates a screen that can be dragged in any direction (horizontal and vertical) with a scaling effect that responds to the gesture.

Function Signature

DraggableCard(
  config?: Partial<ScreenTransitionConfig>
): ScreenTransitionConfig

Parameters

config
Partial<ScreenTransitionConfig>
default:"{}"
Optional configuration to override preset defaults

Returns

ScreenTransitionConfig
object
Configuration object with multi-directional gesture settings

Implementation Details

Screen Style Interpolator

The preset combines scale with gesture-driven translation:
screenStyleInterpolator: ({ current, progress, layouts: { screen } }) => {
  "worklet";

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

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

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

  return {
    contentStyle: {
      transform: [{ scale }, { translateY: translateY }, { translateX }],
    },
  };
}
Animation behavior:
  • progress = 0: Screen is scaled to 0 (invisible)
  • progress = 1: Screen is at normal size and position
  • progress = 2: Screen scales to 75% as it exits
  • Gesture drag is limited to 50% of screen dimensions in each direction
Gesture values:
  • normalizedX and normalizedY range from -1 to 1
  • Drag resistance is 50% (can drag up to half the screen dimension)
  • Uses clamp extrapolation to prevent over-dragging

Transition Spec

transitionSpec: {
  open: {
    stiffness: 1000,
    damping: 500,
    mass: 3,
    overshootClamping: true,
    restSpeedThreshold: 0.02,
  },
  close: {
    stiffness: 1000,
    damping: 500,
    mass: 3,
    overshootClamping: true,
    restSpeedThreshold: 0.02,
  },
}

Usage Examples

import Transition from "react-native-screen-transitions";

<Stack.Screen
  name="Card"
  options={{
    ...Transition.Presets.DraggableCard(),
  }}
/>

Common Use Cases

  • Dismissible cards - Cards that can be swiped away in any direction
  • Image viewers - Photos that can be dragged to dismiss
  • Interactive modals - Dialogs with playful, gesture-driven behavior
  • Tinder-style swipes - Cards that respond to multi-directional input
  • Preview screens - Quick-look overlays that feel tangible

Gesture Behavior

The draggable card responds to both axes simultaneously:
// Gesture allows any direction
gestureDirection: ["horizontal", "vertical"]

// Dismiss threshold is based on combined velocity and distance
// Users can swipe up, down, left, or right to dismiss

Notes

The scale animation is tied to the progress value, not the gesture. This means the card scales during enter/exit transitions but maintains full size during dragging.
For a more dynamic effect, you can make the scale responsive to drag distance by interpolating based on normalizedX and normalizedY values.
Multi-directional gestures may conflict with scrollable content. Use Transition.ScrollView or Transition.FlatList for proper gesture coordination.