【问题标题】:Expo + React Native: Draw line between coordinates on two type of viewsExpo + React Native:在两种视图的坐标之间画线
【发布时间】:2020-08-21 07:41:01
【问题描述】:

我目前正在使用这个模块:https://github.com/mxmzb/react-native-gesture-detector。我希望能够从创建的点中画一条线。但是,它似乎只输出圆圈。

它有一个“创建手势”视图:

<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}
        />
      ))}
    </>
  );
};

当您在该视图上绘图时,它会使用点勾勒出路径,如下所示:

我希望它是一条平滑的线,而不是上图的一系列圆圈。

【问题讨论】:

  • @ShehanDhaleesha 我快速浏览了一下,但似乎不可能画一条波浪线并获得坐标。
  • 我是否正确假设您已经有了这些点并且您只是想从这些点绘制一条平滑线?
  • @grodzi - 我有上面链接的组件,它具有我想要的所有功能,除了它只在它制作的坐标上添加点。我希望它通过一条线连接,如果这条线是 squiqqly,我希望它是平滑的。
  • @jamesG 如果你使用 slopRadius={1} 会发生什么?

标签: javascript react-native expo gesture-recognition


【解决方案1】:

您将需要像 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

【讨论】:

  • 我很困惑,我看不出这是如何根据用户的触摸画一条线的。 ?
  • 我从您的问题中了解到,您已经可以使用react-native-gesture-detector-library 记录它们。一旦被该组件记录,您就可以使用 svg 来绘制它们。但是,对于这种情况,react-native-gesture-detector 并不是完全必要的,因为来自 React Native 的默认 PanResponder 将完成相同的工作。我将更新答案以包括记录触摸。
  • 您的更新与我想要的非常接近,但我觉得好像我解释错了。您的解决方案没有显示线条,因为我正在绘制“实时”,这是我正在寻找的效果。很抱歉,我是一名初级开发人员,对此非常陌生,所以请原谅我对问题的轰炸。
  • 不用担心。我有点期待 :) 更新了答案和点心,只是多了 1 行。
  • 嘿@mtkopone - 太棒了,非常感谢你付出的所有努力。我真的很感激。比你。
猜你喜欢
  • 2012-06-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-04
  • 1970-01-01
相关资源
最近更新 更多