glance-dom
Version:
Glance DOM library
110 lines (83 loc) • 2.6 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var _log = require('../../utils/log');
var _log2 = _interopRequireDefault(_log);
var _filter2 = require('@arr/filter');
var _filter3 = _interopRequireDefault(_filter2);
var _map = require('@arr/map');
var _map2 = _interopRequireDefault(_map);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function sqr(x) {
return x * x;
}
function distance(base, item) {
return sqr(base.x - item.x) + sqr(base.y - item.y);
}
function distToSegment(base, item1, item2) {
var l = distance(item1, item2);
if (l === 0) return distance(base, item1);
var t = ((base.x - item1.x) * (item2.x - item1.x) + (base.y - item1.y) * (item2.y - item1.y)) / l;
if (t < 0) return distance(base, item1);
if (t > 1) return distance(base, item2);
return distance(base, {
x: item1.x + t * (item2.x - item1.x),
y: item1.y + t * (item2.y - item1.y)
});
}
function getSizeAndLocation(element) {
var rect = element.getBoundingClientRect();
return _extends({
element: element
}, rect, {
x: rect.left,
y: rect.top
});
}
function shortestDistance(a, t) {
var p1 = t;
var p2 = {
x: t.x + t.width,
y: t.y
};
var p3 = {
x: t.x + t.width,
y: t.y + t.height
};
var p4 = {
x: t.x,
y: t.y + t.height
};
return Math.min(distToSegment(a, p1, p2), distToSegment(a, p2, p3), distToSegment(a, p4, p3), distToSegment(a, p1, p4));
}
exports.default = {
options: {
'closest': {
filter: function filter(_ref) {
var elements = _ref.elements,
scopeElements = _ref.scopeElements;
_log2.default.debug('Filtering for closest element to scope');
return (0, _map2.default)(scopeElements, function (scope) {
var base = getSizeAndLocation(scope);
var baseID = base.element;
var a = base;
a.x = a.x + base.width / 2;
a.y = a.y + base.height / 2;
var targets = (0, _map2.default)(elements, function (e) {
return getSizeAndLocation(e);
});
var sorted = (0, _filter3.default)(targets, function (t) {
return t.element !== baseID;
}).sort(function (x, y) {
var l = shortestDistance(a, x);
var r = shortestDistance(a, y);
return l < r ? -1 : l > r ? 1 : 0;
});
return sorted[0].element;
});
}
}
}
};