javascript - 如何从路径连接多个div?

标签 javascript jquery html css

我正在使用 svg 将一个 div 连接到多个 div。目前我只能连接 1 个 div,但无法连接其他 div。我正在申请<path> 。例如,我想连接div A到Bdiv A到C等等,如果有N个div,那么div A 必须连接到 N 个 div:

const $b1 = $("#box1");
const $b2 = $("#box2");
const $line = $("line");
var path = document.querySelector(".path");
const padding = 7;
// Amount to offset control points
var bezierWeight = 0.675;
/* TweenLite.set($b1, { x: 400, y: 150 });
TweenLite.set($b2, { x: 200, y: 350 }); */
const coordinates = function() {
  const x1 = $b1.offset().left + $b1.width()/2-padding;
  const y1 = $b1.offset().top + $b1.height()/2-padding;
  const x4 = $b2.offset().left + $b1.width()/2-padding;
  const y4 = $b2.offset().top + $b1.height()/2-padding;
  var dx = Math.abs(x4 - x1) * bezierWeight;
  var x2 = x1 - dx;
  var x3 = x4 + dx;
  var data = `M${x1} ${y1} C ${x2} ${y1} ${x3} ${y4} ${x4} ${y4}`;
  

  /* $line.attr("x1", x1);
  $line.attr("y1", y1);
  $line.attr("x4", x4);
  $line.attr("y4", y4); */
  path.setAttribute("d", data);
}
coordinates();


$('#box1').draggable({
  drag: coordinates
});

$('#box2').draggable({
  drag: coordinates
});
$('#box3').draggable({
  drag: coordinates
});
.box {
  border: 1px solid black;
  background-color: #ccc;
  width: 100px;
  height: 100px;
  position: absolute;
}


#box1 {
  top: 0;
  left: 200px;
}

#box2 {
  top: 200px;
  left: 0;
}

#box3 {
  top: 200px;
  left: 400px;
}

.path {
  fill: none;
  stroke: dodgerblue;
  stroke-width: 6;
}
<div class="box" id="box1">A</div>
<div class="box" id="box2">B</div>
<div class="box" id="box3">C</div>

<svg height="1000" width="1000">
<path class="path" />  
  <!-- <line id="line" x1="400" y1="150" x2="200" y2="350" style="stroke: rgb(0,0,0); stroke-width:1" /> -->
</svg>


<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.20.2/TweenMax.min.js"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.20.2/utils/Draggable.min.js"></script>

为了进行通用工作,我还尝试申请 $('.box').each(function(index, obj)但每次我都没有得到任何东西。如果我的工作能以通用的方式进行,那就太好了。抱歉英语不好,我正在尽力解释我正在进行的工作的问题。

最佳答案

目前,您使用每个变量的单个变量对要连接的元素进行了硬编码( $b1$b1 )。我建议将一个对象内两个连接框的字符串 ID 分组,并最终将这些对象捆绑在一个数组内。

因此,如果box1连接到box2并且box1连接到box3:

var connections = [{
  boxA: "#box1",
  boxB: "#box2"
}, {
  boxA: "#box1",
  boxB: "#box3"
}];

coordinates()内您正在引用您在 html 代码中设置的另一个硬编码元素的函数: svg <path>

Javascript 有一个内置函数可以动态创建元素 document.createElement() 。然而在这种情况下我们需要 document.createElementNS()因为我们需要指定 svg 命名空间。这样一个动态创建的元素最终可以使用element.appendChild(elementToBeAdded);添加到现有元素中。

所以coordinates()函数需要进行修改,首先删除所有现有路径,迭代连接数组内的所有对象,然后创建所需路径并将其附加到 <svg> .

这是一个例子:

var paths = document.getElementById("paths");
const padding = 7;

var bezierWeight = 0.675;

var connections = [{
  boxA: "#box1",
  boxB: "#box2"
}, {
  boxA: "#box1",
  boxB: "#box3"
}];

const coordinates = function() {

  let oldPaths = paths.children;
  for (let a = oldPaths.length - 1; a >= 0; a--) {
    paths.removeChild(oldPaths[a]);
  }

  let x1, y1, x4, y4, dx, x2, x3, path, boxA, boxB;

  for (let a = 0; a < connections.length; a++) {
    boxA = $(connections[a].boxA);
    boxB = $(connections[a].boxB);

    x1 = boxA.offset().left + boxA.width() / 2 - padding;
    y1 = boxA.offset().top + boxA.height() / 2 - padding;
    x4 = boxB.offset().left + boxA.width() / 2 - padding;
    y4 = boxB.offset().top + boxA.height() / 2 - padding;
    dx = Math.abs(x4 - x1) * bezierWeight;

    if (x4 < x1) {
      x2 = x1 - dx;
      x3 = x4 + dx;
    } else {
      x2 = x1 + dx;
      x3 = x4 - dx;
    }

    data = `M${x1} ${y1} C ${x2} ${y1} ${x3} ${y4} ${x4} ${y4}`;
    path = document.createElementNS("http://www.w3.org/2000/svg", "path");
    path.setAttribute("d", data);
    path.setAttribute("class", "path");
    paths.appendChild(path);
  }
}

coordinates();

$('#box1').draggable({
  drag: coordinates
});

$('#box2').draggable({
  drag: coordinates
});
$('#box3').draggable({
  drag: coordinates
});
.box {
  border: 1px solid black;
  background-color: #ccc;
  width: 100px;
  height: 100px;
  position: absolute;
}

#box1 {
  top: 0;
  left: 200px;
}

#box2 {
  top: 200px;
  left: 0;
}

#box3 {
  top: 200px;
  left: 400px;
}

.path {
  fill: none;
  stroke: dodgerblue;
  stroke-width: 6;
}
<div class="box" id="box1">A</div>
<div class="box" id="box2">B</div>
<div class="box" id="box3">C</div>
<svg height="1000" width="1000" id="paths">
</svg>
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.20.2/TweenMax.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.20.2/utils/Draggable.min.js"></script>

关于javascript - 如何从路径连接多个div?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60186493/

相关文章:

javascript - 无法加载jquery

仅针对特定元素的 JavaScript SelectionChange 事件

html - 如何将 html 代码添加到网站但不将其实际转换为代码?

javascript - 根据质量和弹跳系数计算球与球碰撞的速度和方向

javascript - Typescript:如何使用命名空间中的类或接口(interface)

javascript - 为什么 jQuery 中的 every 不迭代列表中的所有值

jquery - 如何为 jQuery UI 进度条的值设置动画?

html - 如何使用我的 CSS 网格布局设置粘性页脚?

javascript - Angular-一个组件中有两个输出事件,但只有一个有效

jquery - 从 jQuery 中的 select 元素中按值获取选项