1

我正在用 React-Konva 画一条线。绘制线后,我想在该线下方显示一个箭头(两侧都有指针)。该箭头应该比线长(两边),但应该指向相同的方向。

到目前为止,我尝试的是创建一个与线具有相同点的箭头,然后使用该箭头上的比例使其比线长。这可行,但箭头仅在一侧比线长。

截屏

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

有没有一种方法可以用来实现这一点?

4

1 回答 1

1

原则上,您的问题是因为箭头形状是从草图中的 x 和 y 位置 - A 绘制的。您需要做的是计算绘图点移动 0.1 倍线长的位置,然后应用 1.2 比例 X 和 Y。

你可以这样做

  1. 通过起始 pt 为 {x: points[0], y: points[1]} 且结束 pt 与 points[2] 和 [3] 相同的线点获取线的宽度和高度。
  2. 减去 x 得到长度,减去 y 得到高度。
  3. 将每个乘以 0.1 以找到增量 X 和 Y。
  4. 从线 X 和 Y 中减去 deltaX 和 Y 以找到新的绘图点
  5. 使用与线相同的 points[] 数组从那里绘制箭头,比例为 1.2。

任务完成。我不会想到你操纵比例的狡猾解决方案 - 我可能会以与起点相同的方式计算终点,并以 1 的比例在它们之间绘制箭头。

我在下面包含了一个工作片段 - 这是 vanilla JS 而不是反应,但希望它会告诉你方法。

黑线是原始的 Konva 线,箭头位置是根据我上面的解释计算的。

  // 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>

于 2021-01-27T17:46:29.003 回答