简体   繁体   English

在 React-Konva 中增加两侧的箭头

[英]Increase Arrow from both sides in React-Konva

I'm drawing a Line with React-Konva.我正在用 React-Konva 画一条线。 Once the Line is drawn, I would like to display an Arrow (with pointers on both sides) underneath that Line.绘制线后,我想在该线下方显示一个箭头(两边都有指针)。 That Arrow should be longer (both sides) than the Line but should point the same direction.该箭头应比线长(两侧)但应指向相同的方向。

What I've tried so far is to create an Arrow with the same points as the Line, and then using a scale on that Arrow to make it longer than the Line.到目前为止,我尝试过的是创建一个与线具有相同点的箭头,然后在该箭头上使用比例尺使其比线长。 This works, but the Arrow is longer than the Line on just one side.这可行,但箭头仅在一侧比线长。

截屏

<Arrow
 pointerAtBeginning={true}
 scaleX={1.4}
 scaleY={1.4}
 stroke="rgb(0, 61, 55)"
 x={startPoint[0]}
 y={startPoint[1]}
 points={[0, 0, ...endPoint]}
/>

Is there a method I can use to accomplish this?有什么方法可以用来完成这个吗?

In principle your issue is because the arrow shape is drawn from the x & y position - A in your sketch.原则上你的问题是因为箭头形状是从草图中的 x & y position - A 绘制的。 What you need to do is compute the positions for the drawing point moved by 0.1 times the line length, then apply a 1.2 scale X & Y.您需要做的是计算移动 0.1 倍线长的绘图点的位置,然后应用 1.2 比例的 X 和 Y。

You can do this by你可以这样做

  1. Get the width and height of the line via the line points where the starting pt is {x: points[0], y: points[1]} and the ending pt is the same from points[2] and [3].通过起始点为 {x: points[0], y: points[1]} 且结束点与 points[2] 和 [3] 相同的线点获取线的宽度和高度。
  2. Subtract the x's to get length and y's to get the height.减去 x 得到长度,减去 y 得到高度。
  3. Multiply each by.1 to find the delta X & Y.将每个乘以 1 以找到增量 X 和 Y。
  4. Subtract deltaX & Y from the line X & Y to find the new drawing point从直线 X & Y 中减去 deltaX & Y 以找到新的绘图点
  5. Draw you arrow from there using the same points[] array as the line, and scale of 1.2.使用与线相同的 points[] 数组从那里绘制箭头,比例为 1.2。

Job done.任务完成。 I would not have thought of your cunning solution of manipulating the scale - I would likely have computed the end point in the same manner as the start point and drawn the arrow between them at a scale of 1.我不会想到你操纵比例的巧妙解决方案——我可能会以与起点相同的方式计算终点,并在它们之间以 1 的比例绘制箭头。

I include a working snippet below - this is vanilla JS rather than react but hopefully it will show you the way.我在下面包含了一个工作片段——这是 vanilla JS 而不是 React,但希望它能为你指明方向。

The black line is the original Konva line, and the arrow position is computed as per my explanation above.黑线是原始的 Konva 线,箭头 position 是根据我上面的解释计算的。

 // Set up a stage let // Konva housekeeping stage = new Konva.Stage({ container: 'container', width: window.innerWidth, height: window.innerHeight }), // add a layer to draw on layer = new Konva.Layer(), points = [0, 0, 250, -50], drawX = 50, drawY = 100 line = new Konva.Line({ x: drawX, y: drawY, points: points, stroke: 'black', strokeWidth: 3 }); // Add the layer to the stage and shape to layer stage.add(layer); // Make a couple of points to give start and end of line for ease let ptStart = {x: points[0], y: points[1]}, ptEnd = {x: points[2], y: points[3]}; // Compute the width and height of the line let sz = { width: Math.abs(ptEnd.x - ptStart.x), height: Math.abs(ptEnd.y - ptStart.y), } // Compute x & y size of 10% increase let adj = { width: sz.width * 0.1, height: sz.height * 0.1 } // Compute new position of arrow. drawX = drawX - adj.width; drawY = drawY + adj.height // add the arrow at the new position and scaled x 1.2 let arrow = new Konva.Arrow({ x: drawX, y: drawY, points: points, stroke: 'magenta', strokeWidth: 6, opacity: 0.2, pointerAtBeginning: true, scaleX: 1.2, scaleY: 1.2 }); // Job done layer.add(line, arrow) stage.draw();
 * { box-sizing: border-box; } body { margin: 10; padding: 10; overflow: hidden; background-color: #f0f0f0; } #container { border: 1px solid silver; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script src="https://unpkg.com/konva@^3/konva.min.js"></script> <div id="container"></div>

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

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