如何通过其末端/线在组上拖动线

How to drag a line by its ends / line on a group

张贴这个自我回答的问题供我自己将来参考,以防它帮助其他通过这种方式的人。

我有一条直线,两端都有圆圈,用作定位直线的锚点。这些形状在一个组中。我希望用户能够单击并拖动一个圆圈并让线条跟随圆圈移动。

该组是可拖动的,当我拖动任一圆圈时,整个组都会移动 - 我想要的是独立于组拖动圆圈。

const stage = new Konva.Stage({
  container: 'container',
  width: window.innerWidth,
  height: window.innerHeight,
}),
layer = new Konva.Layer({name: 'layer'}),
group = new Konva.Group({name: 'group', draggable: true}),
line = new Konva.Line({
  name: 'the line',
  x: 20,
  y: 20,
  points: [0, 0, 500, 200],
  strokeWidth: 5,
  stroke: 'cyan'
}),
circle1 = new Konva.Circle({
  name: 'circle1',
  x: 20,
  y: 20,
  radius: 10,
  fill: 'magenta'
}),
circle2 = circle1.clone({name: 'circle2', x: 520, y: 220, fill: 'magenta'});

group.add(line, circle1, circle2)
stage.add(layer)
layer.add(group);

// What next ?

 
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://unpkg.com/konva@8.3.2/konva.min.js"></script>
    <div id="container"></div>

找到答案:使圆圈可拖动,然后使用拖动的圆圈的位置给出将线的适当末端移动到的位置。

当形状在一个组中时,它们的位置是相对于父组的。我想知道这是否会成为并发症。然而,由于直线和圆圈都是同一组父级的子级,我们可以通过简单的 shape.position() 调用来找到我们需要的位置。 shape.position() 获取相对于父级的位置。为了将来参考,您可以使用 getAbsolutePosition() 来查找相对于舞台的位置,但在这种情况下您不需要它,因为所有形状都在同一个父级上,因此一切都相对于该父级。

const stage = new Konva.Stage({
  container: 'container',
  width: window.innerWidth,
  height: window.innerHeight,
}),
layer = new Konva.Layer({name: 'layer'}),
group = new Konva.Group({name: 'group', draggable: true}),
line = new Konva.Line({
  name: 'the line',
  x: 20,
  y: 20,
  points: [0, 0, 500, 200],
  strokeWidth: 5,
  stroke: 'cyan'
}),
circle1 = new Konva.Circle({
  name: 'circle1',
  x: 20,
  y: 20,
  radius: 10,
  fill: 'magenta',
  draggable: true
}),
circle2 = circle1.clone({name: 'circle2', x: 520, y: 220, fill: 'magenta'});

group.add(line, circle1, circle2)
stage.add(layer)
layer.add(group);


circle1.on('dragmove', function(event){
  const circle1Pos = circle1.getPosition(),
        circle2Pos = circle2.getPosition();  
  line.position(circle1Pos);
  line.points([0, 0, circle2Pos.x - circle1Pos.x, circle2Pos.y - circle1Pos.y])
})

circle2.on('dragmove', function(event){
  const linePos = line.getPosition(),
        circle2Pos = circle2.getPosition();  
  line.points([0, 0, circle2Pos.x - linePos.x, circle2Pos.y - linePos.y])
})
  
<script src="https://unpkg.com/konva@8.3.2/konva.min.js"></script>
<p>Click & drag circles to reposition the line. Drag line to move group.</p>
    <div id="container"></div>