Dragging (experimental)

Simplifying interactivity is a core aim for Pose on the web, and the same is true for React Native Pose.

Currently, it offers experimental dragging support. In this tutorial, we’ll:

  • Make a component draggable
  • Hook into the special dragging and dragEnd poses
  • Use the onDragStart and onDragEnd callbacks

Dragging

To make a component draggable set draggable: true in the posed component config:

const config = {
  draggable: true
};

true sets both axis to draggable, but we can select a single axis to drag on by setting it to 'x' or 'y':

const config = {
  draggable: 'x'
}

Special poses

When dragging, two special poses become available. dragging, and dragEnd.

These two poses will be set automatically and will propagate throughout the component’s children as normal.

For instance, we could make a component that increases in scale while the user’s dragging:

const config = {
  draggable: true,
  dragging: { scale: 1.2 },
  dragEnd: { scale: 1 }
};

Both of these poses gets provided PanResponder’s gestureState object, so we can make different animations based on the behaviour of the drag:

const config = {
  draggable: 'x',
  dragEnd: {
    x: 0,
    transition: ({ value, toValue, gestureState }) => {
      return gestureState.dx > 50 || gestureState.dx < -50
        ? Animated.decay(value, { velocity: gestureState.vx })
        : Animated.spring(value, { toValue })
    }
  }
}

onDragStart/onDragEnd

If onDragStart or onDragEnd callbacks are provided to the component, they’ll be called with the same arguments as PanResponder’s onPanResponderGrant and onPanResponderRelease callbacks.

<DraggableComponent onDragEnd={(e, gestureState) => {}} />

Coming soon

Pose for the web has a dragBounds property that can clamp movement to within a specified range. This feature will come to React Native Pose in the coming weeks.

In the longer term we want to introduce a range of properties like snap points, but the serialisable nature of Animated’s API makes this difficult compared to the functional API of Popmotion.

Dragging via Interactable

Wix’s Interactable library is a declarative way of introducing interactions at the component level and is compatible with React Native Pose. If you use it be careful not to set draggable: true on the posed component otherwise Pose will disable the native driver.

const PosedComponent = posed()(config);

export default () => (
  <PosedComponent pose="poseName">
    {({ x, y }) => (
      <Interactable.View
        animatedValueX={x}
        horizontalOnly={true}
        snapPoints={[{x: 0}, {x: -200}]}
      />
    )}
  </PosedComponent>
)