Skip to content

Instantly share code, notes, and snippets.

@Rycochet
Last active August 29, 2015 13:58
Show Gist options
  • Save Rycochet/10250178 to your computer and use it in GitHub Desktop.
Save Rycochet/10250178 to your computer and use it in GitHub Desktop.
Draw a line from one element to another, use $(sel).drawLine("update") to refresh positions etc
/**
* Draw a line between two elements
* @param {(jQuerySelector|string)} target
* @param {?Object} options
* @returns {jQuerySelector}
*/
$fn.drawLine = function(target, options) {
var opts,
_uiLine = "ui-line",
get_relative = function(from_pos, from_size, to_pos, to_size, small, big, corners) {
if (from_pos + (corners ? from_size / 4 : 0) > to_pos + to_size) {
return small;
}
if (from_pos + (corners ? from_size / 4 * 3 : from_size) < to_pos) {
return big;
}
return "center";
},
get_auto = function(from, to, rel, corners) {
if (rel.indexOf("auto") >= 0) {
rel = rel.split(" ");
var pos_from = from.offset(),
from_width = from.width(),
from_height = from.height(),
pos_to = to.offset();
rel[1] = rel[1] || rel[0];
if (rel[0] === "auto") {
rel[0] = get_relative(pos_from.left, from_width, pos_to.left, to.width(), "left", "right", corners);
}
if (rel[1] === "auto") {
rel[1] = get_relative(pos_from.top, from_height, pos_to.top, to.height(), "top", "bottom", corners);
}
rel = rel.join(" ");
if (!corners && rel.indexOf("center") === -1) {
rel = rel.replace(from_height > from_width ? /(left|right)/i : /(top|bottom)/i, "center");
}
}
return rel;
};
if (target === "destroy") {
target = null;
} else if (target !== "update") {
opts = $.extend(true, {}, $fn.drawLine.options, options, {
"to": {
"of": $(target),
"collision": "none"
},
"from": {
// "of": filled in later
"collision": "none"
}});
opts.to.at = opts.to.my;
opts.from.at = opts.from.my;
opts.to.my = opts.from.my = "center";
}
return this.each(function(i, el) {
var from, to, $el = $(el), $line = $el.data(_uiLine);
if ($el.data(_uiLine + "-parent")) {
$line = $el;
$el = $el.data(_uiLine + "-parent");
}
if (target && target.length) {
if (!opts || target === "update") {
opts = $el.data(_uiLine + "-options");
if (!opts) {
return;
}
} else {
$el.data(_uiLine + "-options", $.extend({}, opts));
}
opts.from.of = opts.source ? $(opts.source, $el) : $el;
if (!$line) {
$line = $("<hr class=\"ui-helper-reset ui-line\">").appendTo($el);
$el.data(_uiLine, $line);
}
$line
.css({
"width": "",
"transform": ""
})
.data(_uiLine + "-parent", $el)
.position($.extend({}, opts.to, {
"at": get_auto(opts.to.of, opts.from.of, opts.to.at, opts.corners),
"using": function(pos) {
to = pos;
}}
))
.position($.extend({}, opts.from, {
"at": get_auto(opts.from.of, opts.to.of, opts.from.at, opts.corners),
"using": function(pos) {
from = pos;
}}
))
.css({
"top": from.top + "px",
"left": from.left + "px",
"width": Math.sqrt(Math.pow(from.left - to.left, 2) + Math.pow(from.top - to.top, 2)) + "px",
"transform": "rotate(" + Math.atan2(to.top - from.top, to.left - from.left) + "rad)"
});
} else {
if ($el.data(_uiLine)) {
$el.data(_uiLine).remove();
}
$el.removeData([_uiLine, _uiLine + "-options"]);
}
});
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment