Drag with react native skia and reanimated
Siso Ngqolosi
Published on Thursday, Feb 1, 2024
In this tutorial, we will be building a simple app that allows you to move a red circle around the screen using touch gestures. We will leverage the power of React Native Skia to create smooth and performant animations, and we will also use React Native Reanimated to handle gesture events efficiently.
Prerequisites:
Before we start, make sure you have the following set up:Node.js
and npm (or yarn)
installed on your machine.
Basic familiarity with React Native development.
The required libraries installed: @shopify/react-native-skia react-native-reanimated
import { GestureResponderEvent } from 'react-native';
import React from 'react';
import { Canvas, Circle, Fill } from '@shopify/react-native-skia';
import { useSharedValue } from 'react-native-reanimated'
Manage Circles Position with Shared Values:
const circleLocationX = useSharedValue(200);
const circleLocationY = useSharedValue(200);
Handle Touch Events:
const handleMoveEvent = (event: GestureResponderEvent) => {
'worklet';
const { locationX, locationY } = event.nativeEvent;
circleLocationX.value = locationX;
circleLocationY.value = locationY;
};
Render the Canvas and Circle:
<Canvas
// ...
>
<Fill color="#120a3d" />
<Circle cx={circleLocationX} cy={circleLocationY} r={100} color="red" />
</Canvas>
};
Shared Values: We use useSharedValue from Reanimated to create smooth animations when updating the circles position.
Touch Events: The handleMoveEvent function tracks touch gestures and updates the circles coordinates accordingly.
Canvas and Circle: The Canvas component provides the drawing surface, and the Circle component renders the draggable circle.
Then install react-native-skottie
npm install @shopify/react-native-skia react-native-reanimated
Link the libraries (if necessary):
npx pod-install
npm i react-native-reanimated
Add react-native-reanimated/plugin plugin to your babel.config.js.
module.exports = {
presets: [
... // don't add it here :)
],
plugins: [
...
'react-native-reanimated/plugin',
],
};
Here is the rest of the code
import React from 'react';
import {Canvas, Circle, Fill} from '@shopify/react-native-skia';
import {useSharedValue} from 'react-native-reanimated';
import {GestureResponderEvent} from 'react-native';
const App = () => {
const circleLocationX = useSharedValue(200);
const circleLocationY = useSharedValue(200);
const handleMoveEvent = (event: GestureResponderEvent) => {
'worklet';
const {locationX, locationY} = event.nativeEvent;
circleLocationX.value = locationX;
circleLocationY.value = locationY;
};
return (
<>
<Canvas
style={{
flex: 1,
width: '100%',
height: 'auto',
}}
onTouchStart={e => {
console.log('onTouchStart');
handleMoveEvent(e);
}}
onTouchMove={handleMoveEvent}
onTouchEnd={e => {
console.log('onTouchEnd');
}}>
<Fill color="#120a3d" />
<Circle cx={circleLocationX} cy={circleLocationY} r={100} color="red" />
</Canvas>
</>
);
};
export default App;