I am currently using this module: https://github.com/mxmzb/react-native-gesture-detector. I want to be able to draw a line from the points created. however, it only seems to output circles.
It has a “Create Gesture” view:
<View style={{ position: "relative", width: "100%", height: "100%" }}> <GesturePath path={gesture.map(coordinate => { if (recorderOffset) { return { x: coordinate.x + recorderOffset.x, y: coordinate.y + recorderOffset.y, }; } return coordinate; })} color="green" slopRadius={30} center={false} /> </View>
GesturePath is defined like so:
const GesturePath = ({ path, color, slopRadius, center = true }: GesturePathProps) => { const baseStyle: ViewStyle = { position: "absolute", top: center ? "50%" : 0, left: center ? "50%" : 0, opacity: 1, }; return ( <> {path.map((point, index) => ( <Animated.View style={Object.assign({}, baseStyle, { width: slopRadius, height: slopRadius, borderRadius: slopRadius, backgroundColor: color, marginLeft: point.x - slopRadius, marginTop: point.y - slopRadius, })} key={index} /> ))} </> ); };
When you draw on that view, it outlines the path using dots, like so:
I would like it to be a smooth line and not a series of circles that the above image.
Advertisement
Answer
You are going to need something like a Canvas to draw lines instead of pixels (with Views). React Native does not currently come with a Canvas implementation.
The easiest way to do this in expo is to use the react-native-svg
library.
Using that, you can draw a polyline from your gesture data with the following implementation:
import Svg, { Polyline } from 'react-native-svg'; const GesturePath = ({ path, color }) => { const { width, height } = Dimensions.get('window'); const points = path.map(p => `${p.x},${p.y}`).join(' '); return ( <Svg height="100%" width="100%" viewBox={`0 0 ${width} ${height}`}> <Polyline points={points} fill="none" stroke={color} strokeWidth="1" /> </Svg> ); };
You can also record gestures without the react-native-gesture-detector
library by using the in-built React Native PanResponder. Here is an example:
const GestureRecorder = ({ onPathChanged }) => { const pathRef = useRef([]); const panResponder = useRef( PanResponder.create({ onMoveShouldSetPanResponder: () => true, onPanResponderGrant: () => { pathRef.current = []; }, onPanResponderMove: (event) => { pathRef.current.push({ x: event.nativeEvent.locationX, y: event.nativeEvent.locationY, }); // Update path real-time (A new array must be created // so setState recognises the change and re-renders the App): onPathChanged([...pathRef.current]); }, onPanResponderRelease: () => { onPathChanged(pathRef.current); } }) ).current; return ( <View style={StyleSheet.absoluteFill} {...panResponder.panHandlers} /> ); }
See this snack for a working App tying everything together: https://snack.expo.io/@mtkopone/draw-gesture-path