简体   繁体   English

React-konva 带箭头的双连接对象

[英]React-konva double connected objects with arrow

I'm trying to expand the Connected Objects demo by allowing two nodes (shapes of Circle class) to be double referenced (A connects to B with Arrow1 and B connects to A with Arrow2 ).我试图扩大连接的对象,通过让两个节点(形状演示Circle类)被双引用(A连接到B与Arrow1和B连接到与Arrow2 )。 I work with react-konva package.我使用react-konva包。

I have implemented a demo on Code Sandbox with some basic functionality.我已经在Code Sandbox上实现了一个具有一些基本功能的演示。

On line 5 , 6 you'll find the Nodes info, on line 21 there exists a high-order component that creates the Arrow based on the start Node and end Node position.上线56 ,你会发现节点信息,在线21存在,基于起始节点和终端节点位置创建箭高阶组件。

In the default example, the arrows are working as expected.在默认示例中,箭头按预期工作。 If you try to set the value of redNode.x to 300 the arrows overlap.如果您尝试将redNode.x的值设置为300则箭头会重叠。 The same happens when blueNode.x is equal to -100 .blueNode.x等于-100blueNode.x发生同样的情况。 This has something to do with the way I calculate the arrows (I suspect the equations on line 38 ).这与我计算箭头的方式有关(我怀疑第38行的方程)。

Also note that as redNode.x moves to value 300 , the two arrows approach each other (this happens on other values too), which is something I do not want to happen.另请注意,当redNode.x移动到值300 ,两个箭头彼此接近(这也会发生在其他值上),这是我不希望发生的事情。 I expect the arrows to have the same shape when the two nodes change position and not to overlap or approach each other.我希望当两个节点改变位置并且不重叠或彼此接近时,箭头具有相同的形状。 Unfortunately, my lack of mathematics does not help me solve the problem.不幸的是,我缺乏数学并不能帮助我解决问题。 I also tried to create a custom shape using quadraticCurveTo method without success.我还尝试使用quadraticCurveTo方法创建自定义形状,但没有成功。

Thanks in advance for the help.在此先感谢您的帮助。 I appreciate all the solutions.我很欣赏所有的解决方案。

There are many ways to make curved lines.有很多方法可以制作曲线。 Here is my attempt to make it better:这是我试图让它变得更好的尝试:

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM