在 React-Konva 中增加两侧的箭头
Increase Arrow from both sides in React-Konva
我正在用 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]}
/>
有什么方法可以实现吗?
原则上你的问题是因为箭头形状是从草图中的 x 和 y 位置 - A 绘制的。您需要做的是计算移动 0.1 倍线长的绘图点的位置,然后应用 1.2 比例的 X 和 Y。
您可以通过
- 通过起始点为{x:points[0],y:points[1]}且结束点与points[2]相同的线点获取线段的宽和高[3].
- 减去 x 得到长度,减去 y 得到高度。
- 将每个乘以 .1 得到增量 X 和 Y。
- 从直线 X & Y 中减去 deltaX & Y 找到新的绘图点
- 使用与线相同的点[]数组从那里绘制箭头,比例为 1.2。
工作完成。我不会想到您操纵比例的巧妙解决方案 - 我可能会以与起点相同的方式计算终点,并以 1 的比例在它们之间绘制箭头。
我在下面包含了一个工作片段 - 这是 vanilla JS 而不是 React,但希望它能为你指明方向。
黑线是原来的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>
我正在用 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]}
/>
有什么方法可以实现吗?
原则上你的问题是因为箭头形状是从草图中的 x 和 y 位置 - A 绘制的。您需要做的是计算移动 0.1 倍线长的绘图点的位置,然后应用 1.2 比例的 X 和 Y。
您可以通过
- 通过起始点为{x:points[0],y:points[1]}且结束点与points[2]相同的线点获取线段的宽和高[3].
- 减去 x 得到长度,减去 y 得到高度。
- 将每个乘以 .1 得到增量 X 和 Y。
- 从直线 X & Y 中减去 deltaX & Y 找到新的绘图点
- 使用与线相同的点[]数组从那里绘制箭头,比例为 1.2。
工作完成。我不会想到您操纵比例的巧妙解决方案 - 我可能会以与起点相同的方式计算终点,并以 1 的比例在它们之间绘制箭头。
我在下面包含了一个工作片段 - 这是 vanilla JS 而不是 React,但希望它能为你指明方向。
黑线是原来的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>