创建一个拖动和捕捉行为,将两个元素与JavaScript中的一行连接起来

时间:2017-12-12 17:03:26

标签: javascript jquery

我正在寻找一种干净的方式来创造一个'拖放'& '捕捉'效果,将一条线连接的点拖动到指定点。

常见的参考是图中的连接器。

我为你们画了一个快速的图像:

enter image description here

我已经审核了几个选项

是否有任何可行的解决方案不需要我使用会产生大量开销的大型库。

我目前的尝试是使用jQuery Droppable和jQuery-connections 但是当我拖动它时,我似乎无法正确地将线连接到点。

欢迎任何帮助。 : - )

$(function() {
  $("#dot1").draggable({
    revert: "invalid",
    drag : function(){
        $(this).connections('update')
      }
  });
  $(document).ready(function() {
    $('#bar1').connections({
      to: '#dot1' 
    });
  });
});
.container {
  height: 300px;
}

.bar {
  background: blue;
  width: 50px;
  height: 12px;
  display: block;
  margin-bottom: 50px;
}

.dot {
  height: 8px;
  width: 8px;
  border: 1px solid black;
  border-radius: 50%;
  background: #fff;
  display: block;
  float: right;
  margin-right: -4px;
  margin-top: 1px;
}
<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>

<div class="container">

  <span id="bar1" class="bar">
  <span id="dot1" class="dot"></span>
  </span>

  <span id="bar2" class="bar">
  <span id="dot2" class="dot"></span>
  </span>

</div>

<script>
  ! function(t) {
    t.fn.connections = function(o) {
      return "update" === o ? i(a, this) : "remove" === o ? i(n, this) : (o = t.extend(!0, {
        borderClasses: {},
        class: "connection",
        css: {},
        from: this,
        tag: "connection",
        to: this,
        within: ":root"
      }, o), e(o), this)
    }, t.event.special.connections = {
      teardown: function(e) {
        i(n, t(this))
      }
    };
    var e = function(e) {
        var n = e.borderClasses,
          r = e.tag,
          a = t(e.from),
          i = t(e.to),
          c = t(e.within);
        delete e.borderClasses, delete e.tag, delete e.from, delete e.to, delete e.within, c.each(function() {
          var t = this,
            c = new Array;
          a.each(function() {
            var a = this;
            c.push(this), i.not(c).each(function() {
              o(t, [a, this], r, n, e)
            })
          })
        })
      },
      o = function(e, o, n, r, i) {
        var c = t.extend({
            position: "absolute"
          }, i.css),
          s = t("<" + n + "/>", i).css(c);
        s.appendTo(e);
        var d = (s.outerWidth() - s.innerWidth()) / 2,
          h = (s.outerHeight() - s.innerHeight()) / 2;
        d <= 0 && h <= 0 && (d = h = 1);
        var f = {
          borderClasses: r,
          border_h: h,
          border_w: d,
          node_from: t(o[0]),
          node_to: t(o[1]),
          nodes_dom: o,
          css: c
        };
        "none" === s.css("border-top-style") && (f.css.borderStyle = "solid"), t.data(s.get(0), "connection", f), t.data(s.get(0), "connections", [s.get(0)]);
        for (var m = 0; m < 2; m++) {
          var l = s.add(t.data(o[m], "connections")).get();
          t.data(o[m], "connections", l), 1 == l.length && t(o[m]).on("connections.connections", !1)
        }
        a(s.get(0))
      },
      n = function(e) {
        for (var o = t.data(e, "connection").nodes_dom, n = 0; n < 2; n++) {
          var r = t(t.data(o[n], "connections")).not(e).get();
          t.data(o[n], "connections", r)
        }
        t(e).remove()
      },
      r = function(t) {
        t.rect_from = t.nodes_dom[0].getBoundingClientRect(), t.rect_to = t.nodes_dom[1].getBoundingClientRect();
        var e = t.cache;
        if (t.cache = [t.rect_from.top, t.rect_from.right, t.rect_from.bottom, t.rect_from.left, t.rect_to.top, t.rect_to.right, t.rect_to.bottom, t.rect_to.left], t.hidden = 0 == (t.cache[0] | t.cache[1] | t.cache[2] | t.cache[3]) || 0 == (t.cache[4] | t.cache[5] | t.cache[6] | t.cache[7]), t.unmodified = !0, void 0 === e) return t.unmodified = !1;
        for (var o = 0; o < 8; o++)
          if (e[o] !== t.cache[o]) return t.unmodified = !1
      },
      a = function(e) {
        var o = t.data(e, "connection");
        if (r(o), !o.unmodified) {
          var n = o.border_h,
            a = o.border_w,
            i = (o.node_from, o.node_to, o.rect_from),
            c = o.rect_to,
            s = (i.bottom + i.top) / 2,
            d = (c.left + c.right) / 2,
            h = (c.bottom + c.top) / 2,
            f = (i.left + i.right) / 2,
            m = ["right", "left"];
          if (f > d) {
            m = m.reverse();
            u = Math.max(d - a / 2, Math.min(i.right, c.right));
            d = f + a / 2, f = u
          } else f -= a / 2, d = Math.min(d + a / 2, Math.max(i.left, c.left));
          var l = ["bottom", "top"];
          if (h > s) {
            l = l.reverse();
            var u = Math.max(s - n / 2, Math.min(i.bottom, c.bottom));
            s = h + n / 2, h = u
          } else s = Math.min(s, Math.max(i.top, c.top)), h -= n / 2;
          var b = d - f,
            g = s - h;
          b < a && (h = Math.max(h, Math.min(i.bottom, c.bottom)), s = Math.min(s, Math.max(i.top, c.top)), d = f = ((f = Math.max(i.left, c.left)) + (d = Math.min(i.right, c.right)) - a) / 2), g < n && (f = Math.max(f, Math.min(i.right, c.right)), d = Math.min(d, Math.max(i.left, c.left)), s = h = ((h = Math.max(i.top, c.top)) + (s = Math.min(i.bottom, c.bottom)) - n) / 2), g = s - h, (b = d - f) <= 0 && (n = 0), g <= 0 && (a = 0);
          var v = "border-" + l[0] + "-" + m[0] + "-radius: 0;border-" + l[0] + "-" + m[1] + "-radius: 0;border-" + l[1] + "-" + m[0] + "-radius: 0;";
          if ((n <= 0 || a <= 0) && (v += "border-" + l[1] + "-" + m[1] + "-radius: 0;"), o.hidden) v += "display: none;";
          else {
            o.css["border-" + l[0] + "-width"] = 0, o.css["border-" + m[0] + "-width"] = 0, o.css["border-" + l[1] + "-width"] = n, o.css["border-" + m[1] + "-width"] = a;
            var _ = e.getBoundingClientRect();
            o.css.left = e.offsetLeft + f - _.left, o.css.top = e.offsetTop + h - _.top, o.css.width = b - a, o.css.height = g - n
          }
          var p = o.borderClasses;
          t(e).removeClass(p[l[0]]).removeClass(p[m[0]]).addClass(p[l[1]]).addClass(p[m[1]]).attr("style", v).css(o.css)
        }
      },
      i = function(e, o) {
        return o.each(function() {
          var o = t.data(this, "connections");
          if (o instanceof Array)
            for (var n = 0, r = o.length; n < r; n++) e(o[n])
        })
      }
  }(jQuery);
</script>

0 个答案:

没有答案