Skip to main content
Version: 3.x

Rotation gesture

Loading...

A continuous gesture that can recognize a rotation gesture and track its movement.

The gesture activates when fingers are placed on the screen and rotate around a common point.

Gesture callback can be used for continuous tracking of the rotation gesture. It provides information about the gesture such as the amount rotated, the focal point of the rotation (anchor), and its instantaneous velocity.

Example

import { StyleSheet } from 'react-native';
import {
GestureDetector,
GestureHandlerRootView,
useRotationGesture,
} from 'react-native-gesture-handler';
import Animated, {
useSharedValue,
useAnimatedStyle,
} from 'react-native-reanimated';

export default function App() {
const rotation = useSharedValue(1);

const rotationGesture = useRotationGesture({
onUpdate: (e) => {
rotation.value = savedRotation.value + e.rotation;
},
});

const animatedStyle = useAnimatedStyle(() => ({
transform: [{ rotateZ: `${(rotation.value / Math.PI) * 180}deg` }],
}));

return (
<GestureHandlerRootView style={styles.container}>
<GestureDetector gesture={rotationGesture}>
<Animated.View style={[styles.box, animatedStyle]} />
</GestureDetector>
</GestureHandlerRootView>
);
}

const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'space-around',
},
box: {
height: 120,
width: 120,
backgroundColor: '#b58df1',
borderRadius: 20,
marginBottom: 30,
},
});

Remarks

  • When implementing rotation based on anchor point, make sure to use it after gesture has activated, i.e. in onActivate or onUpdate callbacks. Using it in onBegin may lead to unexpected behavior.

Config

Properties supporting SharedValue can be updated dynamically via Reanimated Shared Values without triggering a re-render.

manualActivation

manualActivation: boolean | SharedValue<boolean>;

When true the handler will not activate by itself even if its activation criteria are met. Instead you can manipulate its state using state manager.

enabled

enabled: boolean | SharedValue<boolean>;

Indicates whether the given handler should be analyzing stream of touch events or not. When set to false we can be sure that the handler will never activate. If the value gets updated while the handler already started recognizing a gesture, then the handler will stop processing gestures immediately. Default value is true.

shouldCancelWhenOutside

shouldCancelWhenOutside: boolean | SharedValue<boolean>;

When true the handler will stop recognition whenever the finger leaves the area of the connected view. Default value of this property is different depending on the handler type. Most handlers' shouldCancelWhenOutside property defaults to false except for the LongPressGesture and TapGesture which default to true.

hitSlop

hitSlop: HitSlop | SharedValue<HitSlop>;
type HitSlop =
| number
| null
| undefined
| Partial<
Record<
'left' | 'right' | 'top' | 'bottom' | 'vertical' | 'horizontal',
number
>
>
| Record<'width' | 'left', number>
| Record<'width' | 'right', number>
| Record<'height' | 'top', number>
| Record<'height' | 'bottom', number>;

This parameter enables control over what part of the connected view area can be used to begin recognizing the gesture. When a negative number is provided the bounds of the view will reduce the area by the given number of points in each of the sides evenly.

Instead you can pass an object to specify how each boundary side should be reduced by providing different number of points for left, right, top or bottom sides. You can alternatively provide horizontal or vertical instead of specifying directly left, right or top and bottom. Finally, the object can also take width and height attributes. When width is set it is only allow to specify one of the sides right or left. Similarly when height is provided only top or bottom can be set. Specifying width or height is useful if we only want the gesture to activate on the edge of the view. In which case for example we can set left: 0 and width: 20 which would make it possible for the gesture to be recognize when started no more than 20 points from the left edge.

IMPORTANT: Note that this parameter is primarily designed to reduce the area where gesture can activate. Hence it is only supported for all the values (except width and height) to be non positive (0 or lower). Although on Android it is supported for the values to also be positive and therefore allow to expand beyond view bounds but not further than the parent view bounds. To achieve this effect on both platforms you can use React Native's View hitSlop property.

testID

testID: string;

Sets a testID property for gesture object, allowing for querying for it in tests.

cancelsTouchesInView (iOS only)

cancelsTouchesInView: boolean | SharedValue<boolean>;

Accepts a boolean value. When true, the gesture will cancel touches for native UI components (UIButton, UISwitch, etc) it's attached to upon activation. Default value is true.

runOnJS

Requires react-native-reanimated

runOnJS: boolean | SharedValue<boolean>;

If set to true, callbacks will be executed on JS runtime. Can be changed dynamically throughout gesture lifecycle. Defaults to false. For more details, see the runOnJS section.

disableReanimated

Requires react-native-reanimated

disableReanimated: boolean;

If set to true, the gesture will ignore any interaction with Reanimated. This property cannot be changed during the gesture's lifecycle. For more details, see the disableReanimated section.

simultaneousWith

simultaneousWith: Gesture | Gesture[]

Adds a gesture that should be recognized simultaneously with this one.

IMPORTANT: Note that this method only marks the relation between gestures, without composing them. GestureDetector will not recognize the otherGestures and it needs to be added to another detector in order to be recognized.

requireToFail

requireToFail: Gesture | Gesture[]

Adds a relation requiring another gesture to fail, before this one can activate.

IMPORTANT: Note that this method only marks the relation between gestures, without composing them. GestureDetector will not recognize the otherGestures and it needs to be added to another detector in order to be recognized.

block

block: Gesture | Gesture[]

Adds a relation that makes other gestures wait with activation until this gesture fails (or doesn't start at all).

IMPORTANT: Note that this method only marks the relation between gestures, without composing them.GestureDetector will not recognize the otherGestures and it needs to be added to another detector in order to be recognized.

useAnimated

useAnimated: boolean;

Setting this property is set to true ensures that the Animated API functions correctly when useNativeDriver is set to false. The default value is set to false.

activeCursor

activeCursor: ActiveCursor | SharedValue<ActiveCursor>;

This parameter allows to specify which cursor should be used when gesture activates. Supports all CSS cursor values (e.g. "grab", "zoom-in"). Default value is set to "auto".

Callbacks

onBegin

onBegin: (event: RotationHandlerData) => void

Set the callback that is being called when given gesture handler starts receiving touches. At the moment of this callback the handler is not yet in an active state and we don't know yet if it will recognize the gesture at all.

onActivate

onActivate: (event: RotationHandlerData) => void

Set the callback that is being called when the gesture is recognized by the handler and it transitions to the active state.

onDeactivate

onDeactivate: (event: RotationHandlerData, didSucceed: boolean) => void

Set the callback that is being called when the gesture that was recognized by the handler finishes. It will be called only if the handler was previously in the active state.

onFinalize

onFinalize: (event: RotationHandlerData, didSucceed: boolean) => void

Set the callback that is being called when the handler finalizes handling gesture - the gesture was recognized and has finished or it failed to recognize.

onTouchesDown

onTouchesDown: (event: GestureTouchEvent) => void

Set the onTouchesDown callback which is called every time a finger is placed on the screen.

onTouchesMove

onTouchesMove: (event: GestureTouchEvent) => void

Set the onTouchesMove callback which is called every time a finger is moved on the screen.

onTouchesUp

onTouchesUp: (event: GestureTouchEvent) => void

Set the onTouchesUp callback which is called every time a finger is lifted from the screen.

onTouchesCancel

onTouchesCancel: (event: GestureTouchEvent) => void

Set the onTouchesCancel callback which is called every time a finger stops being tracked, for example when the gesture finishes.

onUpdate

onUpdate: (event: RotationHandlerData) => void

Set the callback that is being called every time the gesture receives an update while it's active.

Event data

rotation

rotation: number;

Amount rotated, expressed in radians, from the gesture's focal point (anchor).

rotationChange

rotationChange: number;

The incremental change in rotation since the last event frame. This value represents the difference in radians between the current and previous rotation, rather than the total accumulated rotation of the gesture.

velocity

velocity: number;

Instantaneous velocity, expressed in point units per second, of the gesture.

anchorX

anchorX: number;

X coordinate, expressed in points, of the gesture's central focal point (anchor).

anchorY

anchorY: number;

Y coordinate, expressed in points, of the gesture's central focal point (anchor).

numberOfPointers

numberOfPointers: number;

Represents the number of pointers (fingers) currently placed on the screen.

pointerType

pointerType: PointerType;
enum PointerType {
TOUCH,
STYLUS,
MOUSE,
KEY,
OTHER,
}

Indicates the type of pointer device in use.