我正在寻找一种干净的方式来创造一个'拖放'& '捕捉'效果,将一条线连接的点拖动到指定点。
常见的参考是图中的连接器。
我为你们画了一个快速的图像:
我已经审核了几个选项
是否有任何可行的解决方案不需要我使用会产生大量开销的大型库。
我目前的尝试是使用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>