javascript - KineticJS:在两个形状之间绘制箭头

标签 javascript kineticjs

所以,我想在kineticjs的帮助下创建一个有限状态机可视化器/编辑器,但我遇到了以下场景:

我有两个“节点”,比如说圆形对象(用标签分组),它们可以在我的舞台上拖动。现在我不想单击一个圆圈,按住鼠标并移动它并在两个形状之间添加一个连接(为了简单起见,一个箭头)。

因此,如果我能提供有关如何完成此任务的任何提示,那就太好了,因为我还没有找到解决方案。

要指定它:节点本身应该保持可拖动。我的想法是:添加一个黑色圆圈和一个半径稍小的白色圆圈,将它们分组。然后在dragstart白色圆圈上->拖动节点,在dragstart黑色圆圈上->绘制箭头。

问题是如何绘制一个从一个形状开始并跟随鼠标到达其目标的箭头(可以是另一个节点组 => 到该组的连接或舞台的空白点 => 打开一个覆盖层,让用户选择另一个节点进行绘制或取消绘制)。

我希望这有点容易理解。欲了解更多信息,请随时询问我。

最诚挚的问候, 多米尼克

p.s.:该行为似乎与 lucidchart (dot com) 在创建图表时使用的行为完全相同,所以也许您可以在此处查看他们的演示来更好地理解我想要实现的目标:https://www.lucidchart.com/demo .

最佳答案

首先,为了简单起见,这里介绍如何使用鼠标和 KineticJS 绘制基本线条:http://jsfiddle.net/projeqht/fF3hh/

假设舞台上已有两个圆圈,您需要画一条线将它们连接起来。

我们可以使用e.targetNode选择每个事件(mousedown、mouseup)上的节点,例如:

layer.on("mousedown", function (e) {
  var nodeDown = e.targetNode;
}

layer.on("mouseup", function (e) {
  var nodeUp = e.targetNode;
}

我们需要检查 nodeDown 的父级是否是 Kinetic.Group 其他东西。

  1. 如果目标节点nodeDown有一个 Kinetic.Group 作为父节点,我们可以使用这个 Group 来存储新线,以及第二个目标节点 nodeUp .
  2. 如果目标节点nodeUp没有 Kinetic.Group 作为父级,我们需要查看是否 nodeUp有一个家长组。如果nodeUp有一个 Kinetic.Group 作为父节点,那么我们可以使用该 Group 来存储新线,以及第一个目标节点 nodeDown .
  3. 如果两者都不是nodeDownnodeUp为父级创建一个组,然后我们需要为它们创建一个新组,并将所有 3 个形状(2 个圆形和一条线)添加到该新组中。

使用本教程了解如何将形状从一组移动到另一组:http://www.html5canvastutorials.com/kineticjs/html5-canvas-move-shape-to-another-container-with-kineticjs/

此外,如果将形状从一组移动到另一组,您可能需要remove()destroy()如果不再需要额外的组。

绘制线条时,您必须禁用拖动形状,以便可以用鼠标拖动和绘制。您可以通过执行类似以下操作来做到这一点:

function stopDrag() {
  for (var i=0; i<layer.children.length; i++) {
    layer.children[i].setDraggable(false);
  }
}

function startDrag() {
  for (var i=0; i<layer.children.length; i++) {
      layer.children[i].setDraggable(true);
  }
}

这将使图层的所有子级都可拖动和不可拖动,但您可能希望通过比 select layer.children 更具体来限制这一点。 。我喜欢在这里使用的一个好技巧是将所有可拖动的组命名为“draggable_shapes”,然后使用 var draggableArray = stage.get('.draggable_shapes')选择所有允许拖动的组,然后您可以循环遍历该数组和 setDraggable() .

另一点需要注意的是,线的 X 和 Y 坐标计算起来会有点棘手,具体取决于它是否有一个组作为父级或图层。如果线已分组,则线的坐标将相对于位置,否则线的坐标将相对于舞台(左上角)。

这将帮助您开始将一条线与两个不同的圆连接起来。如果您希望线条仅在圆的外缘上连接,则由您来执行坐标逻辑。

也许您可能想在每个圆圈后面添加一个透明矩形(属性 opacity: 0 ),以便在鼠标按下该矩形时,您将调用 drawLine()开始画一条线。否则,如果用户单击圆圈,它将拖动该组。至少它具有与清晰图表应用程序类似的功能。

自定义命中函数 ( http://www.html5canvastutorials.com/kineticjs/html5-canvas-kineticjs-custom-hit-function-tutorial/ ) 可能是一种更简洁的方法,但我并不是 100% 使用自定义命中函数,其他人可能更了解。

如果您需要进一步帮助,请告诉我。祝你好运!

关于javascript - KineticJS:在两个形状之间绘制箭头,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17426613/

相关文章:

javascript - 如何创建 4 个级别的 Highcharts 树形图

javascript - TypeError : Object(. ..) 不是使用 useHistory() 钩子(Hook)时的函数

javascript - 如何通过kineticjs中的点之一拉线/多边形?

javascript - 动力学JS : Can I add multiple names to shapes?

javascript - VS2013 : Publish minified bundle created on files outside of the project

javascript - 使 Twitter Bootstrap 模态完全模态

javascript - Backbone .js。正确设置更改事件

javascript - KineticJS - 创建带有渐变描边的样条线

javascript - KineticJS 选择形状并在其正下方显示 div

javascript - Kineticjs 输出滞后