【问题标题】:React-konva double connected objects with arrowReact-konva 带箭头的双连接对象
【发布时间】:2019-12-29 01:07:00
【问题描述】:

我正在尝试通过允许双重引用两个节点(Circle 类的形状)来扩展 Connected Objects 演示(A 使用 Arrow1 连接到 B,B 使用 Arrow2 连接到 A)。我使用react-konva 包。

我已经在Code Sandbox 上实现了一个带有一些基本功能的演示。

56 线上你会找到节点信息,在21 线上有一个基于起始节点和结束节点位置创建箭头的高阶组件。

在默认示例中,箭头按预期工作。如果您尝试将redNode.x 的值设置为300,箭头会重叠。当blueNode.x 等于-100 时也会发生同样的情况。这与我计算箭头的方式有关(我怀疑38 线上的方程式)。

还请注意,当redNode.x 移动到值300 时,两个箭头彼此靠近(这也发生在其他值上),这是我不希望发生的事情。当两个节点改变位置并且不重叠或相互接近时,我希望箭头具有相同的形状。不幸的是,我缺乏数学并不能帮助我解决问题。我还尝试使用quadraticCurveTo 方法创建自定义形状,但没有成功。

提前感谢您的帮助。我感谢所有的解决方案。

【问题讨论】:

    标签: javascript html5-canvas konvajs react-konva konvajs-reactjs


    【解决方案1】:

    有很多方法可以制作曲线。这是我试图让它变得更好的尝试:

    import React from "react";
    import ReactDOM from "react-dom";
    import { Stage, Layer, Circle, Arrow, Text } from "react-konva";
    
    const BLUE_DEFAULTS = {
      x: 100,
      y: 100,
      fill: "blue",
      width: 30,
      height: 30,
      draggable: true
    };
    
    const RED_DEFAULTS = {
      x: 100,
      y: 300,
      fill: "red",
      width: 30,
      height: 30,
      draggable: true
    };
    
    const Edge = ({ node1, node2 }) => {
      const dx = node1.x - node2.x;
      const dy = node1.y - node2.y;
      let angle = Math.atan2(-dy, dx);
    
      const radius = 20;
      const curvePower = 30;
    
      const arrowStart = {
        x: node2.x + -radius * Math.cos(angle + Math.PI),
        y: node2.y + radius * Math.sin(angle + Math.PI)
      };
    
      const arrowEnd = {
        x: node1.x + -radius * Math.cos(angle),
        y: node1.y + radius * Math.sin(angle)
      };
    
      const arrowCurve = {
        x:
          (arrowStart.x + arrowEnd.x) / 2 +
          curvePower * Math.cos(angle + Math.PI / 2),
        y:
          (arrowStart.y + arrowEnd.y) / 2 +
          curvePower * Math.sin(angle - Math.PI / 2)
      };
    
      return (
        <Arrow
          tension={0.2}
          points={[
            arrowStart.x,
            arrowStart.y,
            arrowCurve.x,
            arrowCurve.y,
            arrowEnd.x,
            arrowEnd.y
          ]}
          stroke="#000"
          fill="#000"
          strokeWidth={3}
          pointerWidth={6}
        />
      );
    };
    
    const App = () => {
      const [blueNode, updateBlueNode] = React.useState(BLUE_DEFAULTS);
      const [redNode, updateRedNode] = React.useState(RED_DEFAULTS);
    
      return (
        <Stage width={window.innerWidth} height={window.innerHeight}>
          <Layer>
            <Text text="Drag any node to see connections change" />
            <Edge node1={blueNode} node2={redNode} />
            <Edge node1={redNode} node2={blueNode} />
            <Circle
              {...blueNode}
              onDragMove={e => {
                updateBlueNode({ ...blueNode, ...e.target.position() });
              }}
            />
            <Circle
              {...redNode}
              onDragMove={e => {
                updateRedNode({ ...redNode, ...e.target.position() });
              }}
            />
          </Layer>
        </Stage>
      );
    };
    
    const rootElement = document.getElementById("root");
    ReactDOM.render(<App />, rootElement);
    

    演示:https://codesandbox.io/s/react-konva-double-connected-objects-m5g22

    【讨论】:

    • 这太棒了!我想问你是如何学会计算这些公式的。这与三角学有关,但你能给我推荐一些适合初学者的书吗?类似于“html canvas 的实用三角函数”之类的东西。写一篇博文也是个好主意!
    • 我不知道任何书(可能有一些)。但是这本书/帖子的想法很酷,会考虑到我。只需要学习“无聊”的数学。
    猜你喜欢
    • 2020-01-04
    • 1970-01-01
    • 2019-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多