Expo + React Native:在两种视图的坐标之间画线
Expo + React Native: Draw line between coordinates on two type of views
我目前正在使用这个模块:https://github.com/mxmzb/react-native-gesture-detector。我希望能够从创建的点画一条线。但是,它似乎只输出圆圈。
它有一个 "Create Gesture" 视图:
<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 定义如下:
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}
/>
))}
</>
);
};
当您在该视图上绘制时,它会使用点勾勒出路径,如下所示:
我希望它是一条平滑的线,而不是上图中的一系列圆圈。
您将需要 Canvas 之类的东西来绘制线条而不是像素(使用视图)。 React Native 目前没有 Canvas 实现。
在 expo 中执行此操作的最简单方法是使用 react-native-svg
库。
使用它,您可以通过以下实现从手势数据中绘制多段线:
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>
);
};
您也可以使用内置的 React Native PanResponder 在没有 react-native-gesture-detector
库的情况下录制手势。这是一个例子:
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}
/>
);
}
查看这个将所有内容捆绑在一起的工作应用程序的小吃:https://snack.expo.io/@mtkopone/draw-gesture-path
我目前正在使用这个模块:https://github.com/mxmzb/react-native-gesture-detector。我希望能够从创建的点画一条线。但是,它似乎只输出圆圈。
它有一个 "Create Gesture" 视图:
<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 定义如下:
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}
/>
))}
</>
);
};
当您在该视图上绘制时,它会使用点勾勒出路径,如下所示:
我希望它是一条平滑的线,而不是上图中的一系列圆圈。
您将需要 Canvas 之类的东西来绘制线条而不是像素(使用视图)。 React Native 目前没有 Canvas 实现。
在 expo 中执行此操作的最简单方法是使用 react-native-svg
库。
使用它,您可以通过以下实现从手势数据中绘制多段线:
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>
);
};
您也可以使用内置的 React Native PanResponder 在没有 react-native-gesture-detector
库的情况下录制手势。这是一个例子:
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}
/>
);
}
查看这个将所有内容捆绑在一起的工作应用程序的小吃:https://snack.expo.io/@mtkopone/draw-gesture-path