naviix
Version:
Spatial navigation. Arrow key navigation.
1,075 lines (1,057 loc) • 34.7 kB
JavaScript
/* 这是 1.2.0 版本的 naviix。 */
'use strict';
function _arrayLikeToArray(r, a) {
(null == a || a > r.length) && (a = r.length);
for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
return n;
}
function _createForOfIteratorHelperLoose(r, e) {
var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
if (t) return (t = t.call(r)).next.bind(t);
if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e) {
t && (r = t);
var o = 0;
return function () {
return o >= r.length ? {
done: true
} : {
done: false,
value: r[o++]
};
};
}
throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
function _extends() {
return _extends = Object.assign ? Object.assign.bind() : function (n) {
for (var e = 1; e < arguments.length; e++) {
var t = arguments[e];
for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]);
}
return n;
}, _extends.apply(null, arguments);
}
function _objectWithoutPropertiesLoose(r, e) {
if (null == r) return {};
var t = {};
for (var n in r) if ({}.hasOwnProperty.call(r, n)) {
if (-1 !== e.indexOf(n)) continue;
t[n] = r[n];
}
return t;
}
function _unsupportedIterableToArray(r, a) {
if (r) {
if ("string" == typeof r) return _arrayLikeToArray(r, a);
var t = {}.toString.call(r).slice(8, -1);
return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
}
}
var _excluded = ["wrap", "subs", "locs"],
_excluded2 = ["locs", "wrap", "subs"],
_excluded3 = ["e"];
var dirs = ["up", "right", "down", "left"];
function naviix(rects, config) {
if (config === void 0) {
config = {};
}
var _config = config,
memo = _config.memo,
scroll = _config.scroll;
_config.dev;
var fuzzy = _config.fuzzy;
var formattedRects = formatIpt(rects);
var _getX = getX(formattedRects, {
fuzzy: fuzzy
}),
rawX = _getX.x,
firstInWrap = _getX.firstInWrap,
enterWrapX = _getX.enterWrapX,
exitWrapX = _getX.exitWrapX,
edgeX = _getX.edgeX;
var memoMap = new Map(); // { enter, exit: { up, down, left, right } }
if (scroll) {
return scrollReturn(rawX);
} else if (memo) {
return memoReturn(rawX);
} else {
return genUserX(rawX, firstInWrap);
}
function update(wrapId, newRects) {
var newFormattedRects = formatIpt(newRects);
var _getX2 = getX(newFormattedRects, {
fuzzy: fuzzy
}),
newRawX = _getX2.x,
newFirstInWrap = _getX2.firstInWrap,
newEnterWrapX = _getX2.enterWrapX,
newExitWrapX = _getX2.exitWrapX,
newEdgeX = _getX2.edgeX;
var _cleanByFormattedRect = cleanByFormattedRects(formattedRects, false),
rectsIncludeWrap = _cleanByFormattedRect.rectsIncludeWrap,
i = _cleanByFormattedRect.i;
rectsIncludeWrap[i] = newFormattedRects[0];
mergeMap(rawX, newRawX);
mergeMap(firstInWrap, newFirstInWrap);
mergeMap(enterWrapX, newEnterWrapX);
mergeMap(exitWrapX, newExitWrapX);
mergeMap(edgeX, newEdgeX);
function cleanByFormattedRects(rects, found) {
if (rects == null) return;
for (var _i = 0; _i < rects.length; ++_i) {
var _rects = rects[_i];
var locs = _rects.locs,
subs = _rects.subs,
_rects$wrap = _rects.wrap,
wrap = _rects$wrap === void 0 ? {} : _rects$wrap;
var curWrapId = wrap.id;
var foundTargetWrap = wrapId === curWrapId;
var _found = found || foundTargetWrap;
if (_found) {
locs.forEach(function (_ref) {
var id = _ref.id;
return rawX["delete"](id);
});
firstInWrap["delete"](curWrapId);
exitWrapX["delete"](curWrapId);
edgeX["delete"](curWrapId);
if (found) {
rawX["delete"](curWrapId);
enterWrapX["delete"](curWrapId);
memoMap["delete"](curWrapId);
} else {
var wrapMemo = memoMap.get(curWrapId);
if (wrapMemo && wrapMemo.enter) delete wrapMemo.enter;
}
}
var res = cleanByFormattedRects(subs, _found);
if (res) return res;
if (foundTargetWrap) return {
rectsIncludeWrap: rects,
i: _i
};
}
}
}
function more(wrapId, newRects) {
var edgeXOfWrap = edgeX.get(wrapId);
var _edgeXOfWrap$reduce = edgeXOfWrap.reduce(function (acc, cur) {
if (cur.isWrap) acc[1].push({
wrap: rawX.get(cur.id).origin
});else acc[0].push(rawX.get(cur.id).origin);
return acc;
}, [], []),
edgeXRects = _edgeXOfWrap$reduce[0],
wrapEdgeXRects = _edgeXOfWrap$reduce[1];
var formattedRects = formatIpt(newRects);
Array.prototype.push.apply(formattedRects[0].locs, edgeXRects);
Array.prototype.push.apply(formattedRects[0].subs, wrapEdgeXRects);
var _getX3 = getX(formattedRects, {
fuzzy: fuzzy
}),
_rawX = _getX3.x,
_firstInWrap = _getX3.firstInWrap,
_enterWrapX = _getX3.enterWrapX,
_exitWrapX = _getX3.exitWrapX,
_edgeX = _getX3.edgeX;
// combine rawX
edgeXOfWrap.forEach(function (xId) {
var originRawX = rawX.get(xId);
var moreRawX = _rawX.get(xId);
dirs.forEach(function (dir) {
if (moreRawX.dis[dir] < originRawX.dis[dir]) {
originRawX[dir] = moreRawX[dir];
originRawX.nextWrap[dir] = false;
originRawX.nextSubWrap[dir] = false;
originRawX.dis[dir] = moreRawX.dis[dir];
}
});
});
// combine firstInWrap
mergeMap(firstInWrap, _firstInWrap);
// combine enterWrapX
mergeMap(enterWrapX, _enterWrapX);
// combine exitWrapX
for (var _iterator = _createForOfIteratorHelperLoose(_exitWrapX), _step; !(_step = _iterator()).done;) {
var _step$value = _step.value,
key = _step$value[0],
val = _step$value[1];
if (key === wrapId) {
var originExitWrapX = exitWrapX.get(key);
for (var _iterator2 = _createForOfIteratorHelperLoose(dirs), _step2; !(_step2 = _iterator2()).done;) {
var dir = _step2.value;
Array.prototype.push.apply(originExitWrapX[dir], val[dir]);
}
} else {
exitWrapX.set(key, val);
}
}
// combine edgeX
mergeMap(edgeX, _edgeX);
// replace edgeX, discard edgeX of prev page
edgeX.set(wrapId, edgeX.get(wrapId).filter(function (xs) {
return !edgeXOfWrap.some(function (_xs) {
return _xs.id === xs.id;
});
}));
}
function scrollReturn(x) {
/** 短时记忆 */
var momentCache = [];
return {
scroll: function scroll(newX) {
updateRawXByScroll(x, newX);
},
left: function left(id, _temp) {
var _ref2 = _temp === void 0 ? {} : _temp,
fuzzy = _ref2.fuzzy,
momentCache = _ref2.momentCache;
return getScrollDirX(id, "left", "right", getMinLeftDis, fuzzy, momentCache);
},
up: function up(id, _temp2) {
var _ref3 = _temp2 === void 0 ? {} : _temp2,
fuzzy = _ref3.fuzzy,
momentCache = _ref3.momentCache;
return getScrollDirX(id, "up", "down", getMinUpDis, fuzzy, momentCache);
},
right: function right(id, _temp3) {
var _ref4 = _temp3 === void 0 ? {} : _temp3,
fuzzy = _ref4.fuzzy,
momentCache = _ref4.momentCache;
return getScrollDirX(id, "right", "left", getMinRightDis, fuzzy, momentCache);
},
down: function down(id, _temp4) {
var _ref5 = _temp4 === void 0 ? {} : _temp4,
fuzzy = _ref5.fuzzy,
momentCache = _ref5.momentCache;
return getScrollDirX(id, "down", "up", getMinDownDis, fuzzy, momentCache);
},
update: update,
more: more
};
function getScrollDirX(id, dir, antiDir, calcMinDis, fuzzy, cache) {
var _momentCache = momentCache,
mid = _momentCache[0],
mdir = _momentCache[1],
mtid = _momentCache[2];
if (cache && id === mid && dir === mdir) {
momentCache = [mtid, antiDir, mid];
return (x.get(mtid) || {}).origin || null;
}
var idXInfo = x.get(id);
if (idXInfo == null) return idXInfo;
var dirX = idXInfo[dir];
var dirXIsWrap = idXInfo.nextWrap[dir];
var dirXIsSubWrap = idXInfo.nextSubWrap[dir];
var startLoc = calcLocIfE(idXInfo.origin);
var target = dirX;
if (dirXIsWrap && dirX) {
// exit
// 找到所有父区内所有指向当前区(子区)左边框的矩形
var allDirWrapX = getAllExitWrapX(dirX.id, antiDir);
target = getNextWrapX(allDirWrapX);
} else if (dirXIsSubWrap) {
// enter
// 找到子区内所有指向子区右边框的矩形
var _allDirWrapX = getAllEnterWrapX(dirX.id, antiDir);
target = getNextWrapX(_allDirWrapX);
}
if (target) momentCache = [target.id, antiDir, id];
return target;
function getNextWrapX(allDirWrapX) {
var res = null;
// next direction element
var minLDis = Infinity;
var gotFirstProj = false;
for (var i = 0; i < allDirWrapX.length; ++i) {
var r2Info = x.get(allDirWrapX[i]);
var r2 = r2Info.origin;
var targetLoc = calcLocIfE(r2);
var r2WrapInfo = x.get(r2Info.wrapId);
if (r2WrapInfo != null && !isVisualElement(targetLoc, calcLocIfE(r2WrapInfo.origin))) continue;
var _calcMinDis = calcMinDis(startLoc, targetLoc, fuzzy),
dis = _calcMinDis.dis,
isProj = _calcMinDis.isProj,
isRestrictProj = _calcMinDis.isRestrictProj;
if (dis < minLDis || gotFirstProj && isRestrictProj && dis <= minLDis) {
minLDis = dis;
res = r2;
if (isProj) {
if (isRestrictProj || gotFirstProj) break;
gotFirstProj = true;
}
} else if (gotFirstProj) break;
}
return res;
}
/**
* +--------------+
* | +---+ |
* | | | |
* | +---+ |
* | +----------+ |
* | | +---+ | | +---+
* | | | | | | | < |
* | | +---+ | | +---+
* | | +---+ | |
* | | | | | |
* | | +---+ | |
* | +----------+ |
* +--------------+
*/
function getAllEnterWrapX(wrapId, dir) {
var exitWrapIdX = exitWrapX.get(wrapId)[dir];
return findAllSideXOfWrap(exitWrapIdX, dir);
}
/**
* +---------------+
* +---+ | |
* | | | |
* +---+ | |
* +-------+ | |
* | +---+ | | +---+ |
* | | | | | | < | |
* | +---+ | | +---+ |
* | +---+ | | |
* | | | | | |
* | +---+ | | |
* +-------+ | |
* +---------------+
*/
function getAllExitWrapX(wrapId, dir) {
var enterWrapIdX = enterWrapX.get(wrapId)[dir];
return findAllSideXOfWrap(enterWrapIdX, dir);
}
function findAllSideXOfWrap(wrapX, dir) {
var sideX = [];
(wrapX || []).forEach(function (xId) {
var subExitWrapX = (exitWrapX.get(xId) || {})[dir];
if (subExitWrapX == null) sideX.push(xId);else sideX.push.apply(sideX, findAllSideXOfWrap(subExitWrapX));
});
return sideX;
}
function calcLocIfE(x) {
return x.e == null ? x.loc : getElementAryLoc(x.e);
}
}
}
function memoReturn(x) {
return {
left: function left(id) {
return getMemoizedDirX(id, "left");
},
up: function up(id) {
return getMemoizedDirX(id, "up");
},
right: function right(id) {
return getMemoizedDirX(id, "right");
},
down: function down(id) {
return getMemoizedDirX(id, "down");
},
update: update,
more: more
};
/**
* @param {any} id
* @param {string} dir
* @returns
*/
function getMemoizedDirX(id, dir) {
var idXInfo = x.get(id);
var wrapId = idXInfo.wrapId;
var dirX = idXInfo[dir];
if (dirX == null) return dirX;
var dirXIsWrap = idXInfo.nextWrap[dir];
var dirXIsSubWrap = idXInfo.nextSubWrap[dir];
var memo = memoMap.get(dirX.id) || {};
if (dirXIsWrap) {
// exit
var targetX = null;
var targetXWrapId = null;
if (memo.exit && memo.exit[dir]) targetX = memo.exit[dir];else {
var xInfo = x.get(dirX.id);
if (xInfo.nextSubWrap[dir]) {
// 方向矩形为 wrap
var sibWrap = xInfo[dir];
var sibWrapMemo = memoMap.get(sibWrap.id) || {};
if (sibWrapMemo.enter) {
targetX = sibWrapMemo.enter;
targetXWrapId = sibWrap.id;
}
}
if (targetX == null) targetX = genUserDirX(dir, dirX, dirXIsWrap, dirXIsSubWrap, rawX, firstInWrap);
}
if (targetX == null) return targetX;
if (targetXWrapId == null) targetXWrapId = x.get(targetX.id).wrapId;
if ((memoMap.get(wrapId) || {}).enter !== idXInfo.origin) updateMemo(idXInfo.origin, wrapId); // exit 的起始点
updateMemo(targetX, targetXWrapId);
return targetX;
} else if (dirXIsSubWrap) {
// enter
var _targetX = memo.enter || genUserDirX(dir, dirX, dirXIsWrap, dirXIsSubWrap, rawX, firstInWrap);
if ((memoMap.get(wrapId) || {}).enter !== idXInfo.origin) updateMemo(idXInfo.origin, wrapId); // enter 的起始点
updateMemo(_targetX, dirX.id);
return _targetX;
} else {
updateMemo(dirX, wrapId);
return dirX;
}
function updateMemo(targetX, wrapId) {
var _x$get = x.get(targetX.id),
nextL = _x$get.left,
nextR = _x$get.right,
nextU = _x$get.up,
nextD = _x$get.down,
_x$get$nextSubWrap = _x$get.nextSubWrap,
nextLIsSubWrap = _x$get$nextSubWrap.left,
nextUIsSubWrap = _x$get$nextSubWrap.up,
nextRIsSubWrap = _x$get$nextSubWrap.right,
nextDIsSubWrap = _x$get$nextSubWrap.down,
_x$get$nextWrap = _x$get.nextWrap,
nextLIsWrap = _x$get$nextWrap.left,
nextUIsWrap = _x$get$nextWrap.up,
nextRIsWrap = _x$get$nextWrap.right,
nextDIsWrap = _x$get$nextWrap.down;
// 更新 exit
updateExitMemo(nextLIsSubWrap, nextLIsWrap, nextL, "left", "right");
updateExitMemo(nextUIsSubWrap, nextUIsWrap, nextU, "up", "down");
updateExitMemo(nextRIsSubWrap, nextRIsWrap, nextR, "right", "left");
updateExitMemo(nextDIsSubWrap, nextDIsWrap, nextD, "down", "up");
// 更新 enter
memoMap.set(wrapId, _extends({}, memoMap.get(wrapId), {
enter: targetX
}));
function updateExitMemo(nextDirXIsSubWrap, nextDirXIsWrap, nextDirX, dir, antiDir) {
if (nextDirXIsSubWrap) {
var _extends2;
var _memo = memoMap.get(nextDirX.id) || {};
memoMap.set(nextDirX.id, _extends({}, _memo, {
exit: _extends({}, _memo.exit, (_extends2 = {}, _extends2[antiDir] = targetX, _extends2))
}));
} else if (nextDirXIsWrap) {
var _extends3;
// 更新兄弟 wrap 的 exit
if (nextDirX == null) return;
var _xInfo = x.get(nextDirX.id);
if (!_xInfo.nextSubWrap[dir]) return; // 方向矩形非 wrap
var _sibWrap = _xInfo[dir];
var _memo2 = memoMap.get(_sibWrap.id) || {};
memoMap.set(_sibWrap.id, _extends({}, _memo2, {
exit: _extends({}, _memo2.exit, (_extends3 = {}, _extends3[antiDir] = targetX, _extends3))
}));
}
}
}
}
}
}
function getX(rects, _temp5) {
var _ref6 = _temp5 === void 0 ? {} : _temp5,
notRoot = _ref6.notRoot,
fuzzy = _ref6.fuzzy;
var mergedX = new Map();
var firstInWrap = new Map();
/** 从外部进入 */
var enterWrapX = new Map();
/** 从内部退出 */
var exitWrapX = new Map();
/** 边缘元素,没有被投影包围的元素 */
var edgeX = new Map();
if (!notRoot && rects.length > 1) {
// 位于 root,且区域数量大于 1
var wraps = rects.map(function (info) {
return info.wrap;
});
rects.forEach(function (s) {
firstInWrap.set(s.wrap.id, s.locs[0]);
});
var _getXBySimple = getXBySimple(wraps, {
fuzzy: fuzzy
}),
x = _getXBySimple.x;
improveHelperDataByX(x, true);
mergedX = x;
}
rects.forEach(function (_ref7) {
var locs = _ref7.locs,
subs = _ref7.subs,
wrap = _ref7.wrap,
loop = _ref7.loop;
var subWraps = (subs || []).map(function (s) {
return s.wrap;
});
if (wrap) firstInWrap.set(wrap.id, locs[0]);
var newLocs = locs.concat(subWraps);
var _getXBySimple2 = getXBySimple(newLocs, {
wrap: wrap,
subWraps: subWraps,
loop: loop,
fuzzy: fuzzy
}),
x = _getXBySimple2.x;
improveHelperDataByX(x);
var _getX4 = getX(subs || [], {
notRoot: true,
fuzzy: fuzzy
}),
subsX = _getX4.x,
_firstInWrap = _getX4.firstInWrap,
_enterWrapX = _getX4.enterWrapX,
_exitWrapX = _getX4.exitWrapX,
_edgeX = _getX4.edgeX;
mergedX = new Map(Array.from(mergedX).concat(Array.from(x)).concat(Array.from(subsX)));
firstInWrap = new Map(Array.from(firstInWrap).concat(Array.from(_firstInWrap)));
enterWrapX = new Map(Array.from(enterWrapX).concat(Array.from(_enterWrapX)));
exitWrapX = new Map(Array.from(exitWrapX).concat(Array.from(_exitWrapX)));
edgeX = new Map(Array.from(edgeX).concat(Array.from(_edgeX)));
});
return {
x: mergedX,
firstInWrap: firstInWrap,
enterWrapX: enterWrapX,
exitWrapX: exitWrapX,
edgeX: edgeX
};
function improveHelperDataByX(x, aryRoot) {
for (var _iterator3 = _createForOfIteratorHelperLoose(x), _step3; !(_step3 = _iterator3()).done;) {
var _step3$value = _step3.value,
xId = _step3$value[0],
xInfo = _step3$value[1];
var _xId = Array.isArray(xId) ? [xId] : xId;
var nextWrap = xInfo.nextWrap,
nextSubWrap = xInfo.nextSubWrap,
wrapId = xInfo.wrapId,
surrounded = xInfo.surrounded,
isWrap = xInfo.isWrap;
for (var _iterator4 = _createForOfIteratorHelperLoose(dirs), _step4; !(_step4 = _iterator4()).done;) {
var dir = _step4.value;
if (aryRoot) {
if (!nextWrap[dir]) {
var _extends4;
var _wrapId = xInfo[dir].id;
var gotEnterWrapX = enterWrapX.get(_wrapId);
enterWrapX.set(_wrapId, _extends({}, gotEnterWrapX, (_extends4 = {}, _extends4[dir] = (gotEnterWrapX && gotEnterWrapX[dir] || []).concat(_xId), _extends4)));
}
continue;
}
if (nextWrap[dir]) {
var _extends5;
var gotExitWrapX = exitWrapX.get(wrapId);
exitWrapX.set(wrapId, _extends({}, gotExitWrapX, (_extends5 = {}, _extends5[dir] = (gotExitWrapX && gotExitWrapX[dir] || []).concat(_xId), _extends5)));
}
if (nextSubWrap[dir]) {
var _extends6;
var _wrapId2 = xInfo[dir].id;
var _gotEnterWrapX = enterWrapX.get(_wrapId2);
enterWrapX.set(_wrapId2, _extends({}, _gotEnterWrapX, (_extends6 = {}, _extends6[dir] = (_gotEnterWrapX && _gotEnterWrapX[dir] || []).concat(_xId), _extends6)));
}
}
if (!surrounded) {
edgeX.set(wrapId, (edgeX.get(wrapId) || []).concat({
id: _xId,
isWrap: isWrap
}));
}
}
}
}
function getXBySimple(rects, _temp6) {
var _ref8 = _temp6 === void 0 ? {} : _temp6,
wrap = _ref8.wrap,
_ref8$subWraps = _ref8.subWraps,
subWraps = _ref8$subWraps === void 0 ? [] : _ref8$subWraps,
loop = _ref8.loop,
fuzzy = _ref8.fuzzy;
var sortedX = [].concat(rects);
sortedX.sort(function (s1, s2) {
return s1.loc[0] - s2.loc[0];
});
var sortedY = [].concat(rects);
sortedY.sort(function (s1, s2) {
return s1.loc[1] - s2.loc[1];
});
var dirMap = new Map();
var surroundedI = 0;
var headRect = rects[0];
var tailRect = rects.slice(-1)[0];
var rowLoop = loop === "row";
var colLoop = loop === "col";
rects.forEach(function (s) {
var isHead = headRect === s;
var isTail = tailRect === s;
var sOrderY = sortedY.findIndex(function (e) {
return e.id === s.id;
});
var sOrderX = sortedX.findIndex(function (e) {
return e.id === s.id;
});
// next down element
var minDownDis = Infinity;
var downS = isTail && colLoop ? headRect : wrap; // 默认指向包裹层
var gotDown = downS === headRect;
var gotFirstDProj = false; // 获得过投影后增加 1 次比较
if (gotDown === false) for (var i = sOrderY - 1; i > -1; --i) {
// 从距离元素最近的位置寻找
var s2 = sortedY[i];
var _getMinDownDis = getMinDownDis(s.loc, s2.loc, fuzzy),
dis = _getMinDownDis.dis,
isProj = _getMinDownDis.isProj,
isRestrictProj = _getMinDownDis.isRestrictProj;
if (dis < minDownDis || gotFirstDProj && isRestrictProj && dis <= minDownDis) {
gotDown = true;
downS = s2;
minDownDis = dis;
if (isProj) {
if (isRestrictProj || gotFirstDProj) {
break; // 投影距离是最短距离,无需后续比较
}
surroundedI += 1;
gotFirstDProj = true;
}
} else if (gotFirstDProj) break; // 已经有过投影后的任何否定情况,直接 break 不再比较
}
// next up element
var minUpDis = Infinity;
var upS = isHead && colLoop ? tailRect : wrap;
var gotUp = upS === tailRect;
var gotFirstUProj = false; // 获得过投影后增加 1 次比较
if (gotUp === false) for (var _i2 = sOrderY + 1; _i2 < sortedY.length; ++_i2) {
var _s = sortedY[_i2];
var _getMinUpDis = getMinUpDis(s.loc, _s.loc, fuzzy),
_dis = _getMinUpDis.dis,
_isProj = _getMinUpDis.isProj,
_isRestrictProj = _getMinUpDis.isRestrictProj;
if (_dis < minUpDis || gotFirstUProj && _isRestrictProj && _dis <= minDownDis) {
gotUp = true;
upS = _s;
minUpDis = _dis;
if (_isProj) {
if (_isRestrictProj || gotFirstUProj) break;
surroundedI += _isProj;
gotFirstUProj = true;
} else if (gotFirstUProj) break;
}
}
// next left element
var minLDis = Infinity;
var lS = isHead && rowLoop ? tailRect : wrap;
var gotLeft = lS === tailRect;
var gotFirstLProj = false;
if (gotLeft === false) for (var _i3 = sOrderX - 1; _i3 > -1; --_i3) {
var _s2 = sortedX[_i3];
var _getMinLeftDis = getMinLeftDis(s.loc, _s2.loc, fuzzy),
_dis2 = _getMinLeftDis.dis,
_isProj2 = _getMinLeftDis.isProj,
_isRestrictProj2 = _getMinLeftDis.isRestrictProj;
if (_dis2 < minLDis || gotFirstLProj && _isRestrictProj2 && _dis2 <= minDownDis) {
gotLeft = true;
lS = _s2;
minLDis = _dis2;
if (_isProj2) {
if (_isRestrictProj2 || gotFirstLProj) break;
surroundedI += _isProj2;
gotFirstLProj = true;
}
} else if (gotFirstLProj) break;
}
// next right element
var minRDis = Infinity;
var rS = isTail && rowLoop ? headRect : wrap;
var gotRight = rS === headRect;
var gotFirstRProj = false;
if (gotRight === false) for (var _i4 = sOrderX + 1; _i4 < sortedX.length; ++_i4) {
var _s3 = sortedX[_i4];
var _getMinRightDis = getMinRightDis(s.loc, _s3.loc, fuzzy),
_dis3 = _getMinRightDis.dis,
_isProj3 = _getMinRightDis.isProj,
_isRestrictProj3 = _getMinRightDis.isRestrictProj;
if (_dis3 < minRDis || gotFirstRProj && _isRestrictProj3 && _dis3 <= minDownDis) {
gotRight = true;
rS = _s3;
minRDis = _dis3;
if (_isProj3) {
if (_isRestrictProj3 || gotFirstRProj) break;
surroundedI += _isProj3;
gotFirstRProj = true;
}
} else if (gotFirstRProj) break;
}
dirMap.set(s.id, {
up: upS,
down: downS,
left: lS,
right: rS,
nextWrap: {
// 指向元素是否为包裹层
up: !gotUp,
down: !gotDown,
right: !gotRight,
left: !gotLeft
},
nextSubWrap: {
// 是否内部的包裹层
up: subWraps.includes(upS),
down: subWraps.includes(downS),
right: subWraps.includes(rS),
left: subWraps.includes(lS)
},
wrapId: wrap == null ? "root" : wrap.id,
origin: s,
isWrap: subWraps.includes(s),
surrounded: surroundedI === 4,
dis: {
up: minUpDis,
down: minDownDis,
right: minRDis,
left: minLDis
}
});
});
return {
x: dirMap
};
}
function getMinDownDis(s, s2, fuzzy) {
var x = s[0],
y = s[1],
t1 = s[2],
t2 = s[3];
var x2 = s2[0],
y2 = s2[1],
t1a = s2[2],
t2a = s2[3];
var dis = Infinity;
var isProj = false;
var isRestrictProj = false;
if (y > y2) {
// is below
if (x2 - t1a > x + t1) {
// is right corner
if (fuzzy || x2 - t1a - x - t1 < y - t2 - y2 - t2a) {
dis = getDistance(x + t1, y - t2, x2 - t1a, y2 + t2a);
}
} else if (x2 + t1a < x - t1) {
// is left corner
if (fuzzy || x - t1 - x2 - t1a < y - t2 - y2 - t2a) {
dis = getDistance(x + t1, y - t2, x2 + t1a, y2 + t2a);
}
} else {
// is project
isProj = true;
isRestrictProj = x2 - t1a >= x - t1 && x2 + t1a <= x + t1;
dis = Math.pow(y - t2 - y2 - t2a, 2);
if (y2 + t2a > y - t2) dis = -dis;
}
}
return {
dis: dis,
isProj: isProj,
isRestrictProj: isRestrictProj
};
}
function getMinUpDis(s, s2, fuzzy) {
var x = s[0],
y = s[1],
t1 = s[2],
t2 = s[3];
var x2 = s2[0],
y2 = s2[1],
t1a = s2[2],
t2a = s2[3];
var dis = Infinity;
var isProj = false;
var isRestrictProj = false;
if (y < y2) {
// is above
if (x2 - t1a > x + t1) {
// is right corner
if (fuzzy || x2 - t1a - x - t1 < y2 - t2a - y - t2) {
dis = getDistance(x + t1, y + t2, x2 - t1a, y2 - t2a);
}
} else if (x2 + t1a < x - t1) {
// is left corner
if (fuzzy || x - t1 - x2 - t1a < y2 - t2a - y - t2) {
dis = getDistance(x - t1, y + t2, x2 + t1a, y2 - t2a);
}
} else {
// is project
dis = Math.pow(y2 - t2a - y - t2, 2);
if (y2 - t2a < y + t2) dis = -dis;
isProj = true;
isRestrictProj = x2 - t1a >= x - t1 && x2 + t1a <= x + t1;
}
}
return {
dis: dis,
isProj: isProj,
isRestrictProj: isRestrictProj
};
}
function getMinLeftDis(s, s2, fuzzy) {
var x = s[0],
y = s[1],
t1 = s[2],
t2 = s[3];
var x2 = s2[0],
y2 = s2[1],
t1a = s2[2],
t2a = s2[3];
var dis = Infinity;
var isProj = false;
var isRestrictProj = false;
if (x > x2) {
// is left
if (y2 - t2a > y + t2) {
// is top corner
if (fuzzy || y2 - t2a - y - t2 < x - t1 - x2 - t1a) {
// closer x
dis = getDistance(x - t1, y + t2, x2 + t1a, y2 - t2a);
}
} else if (y2 + t2a < y - t2) {
// is bottom corder
if (fuzzy || y - t2 - y2 - t2a < x - t1 - x2 - t1a) {
// closer x
dis = getDistance(x - t1, y - t2, x2 + t1a, y2 + t2a);
}
} else {
// is project
dis = Math.pow(x - t1 - x2 - t1a, 2);
if (x2 + t1a > x - t1) dis = -dis;
isProj = true;
isRestrictProj = y2 - t2a >= y - t2 && y2 + t2a <= y + t2;
}
}
return {
dis: dis,
isProj: isProj,
isRestrictProj: isRestrictProj
};
}
function getMinRightDis(s, s2, fuzzy) {
var x = s[0],
y = s[1],
t1 = s[2],
t2 = s[3];
var x2 = s2[0],
y2 = s2[1],
t1a = s2[2],
t2a = s2[3];
var dis = Infinity;
var isProj = false;
var isRestrictProj = false;
if (x2 > x) {
// is right
if (y2 - t2a > y + t2) {
// is top corner
if (fuzzy || y2 - t2a - y - t2 < x2 - t1a - x - t1) {
// closer x
dis = getDistance(x + t1, y + t2, x2 - t1a, y2 - t2a);
}
} else if (y2 + t2a < y - t2) {
// is bottom corder
if (fuzzy || y - t2 - y2 - t2a < x2 - t1a - x - t1) {
dis = getDistance(x + t1, y - t2, x2 - t1a, y2 + t2a);
}
} else {
dis = Math.pow(x2 - t1a - x - t1, 2);
if (x2 - t1a < x + t1)
// overlap
dis = -dis;
isProj = true;
isRestrictProj = y2 - t2a >= y - t2 && y2 + t2a <= y + t2;
}
}
return {
dis: dis,
isProj: isProj,
isRestrictProj: isRestrictProj
};
}
function getDistance(x1, y1, x2, y2) {
var dx = x2 - x1;
var dy = y2 - y1;
return dx * dx + dy * dy; // without sqrt
}
function formatIpt(input) {
if (input == null) return;
var aryIpt = Array.isArray(input);
var simpleIpt = aryIpt && (Array.isArray(input[0]) ? typeof input[0][0] === "number" : input[0].loc != null || istanceofHtmlElement(input[0]));
var objIpt = !aryIpt;
var normalIpt = !simpleIpt && !objIpt;
var formatted = null;
if (simpleIpt) {
formatted = [{
locs: input.map(function (s) {
return Array.isArray(s) ? {
id: s,
loc: s
} : getElementNObjLoc(s);
})
}];
} else if (objIpt) {
var wrap = input.wrap,
subs = input.subs,
locs = input.locs,
otherOpts = _objectWithoutPropertiesLoose(input, _excluded);
formatted = [_extends({
locs: formatIpt(locs)[0].locs
}, otherOpts)];
if (subs != null) {
Object.assign(formatted[0], {
subs: formatIpt(input.subs)
});
}
if (wrap != null) {
Object.assign(formatted[0], {
wrap: Array.isArray(wrap) ? {
loc: wrap,
id: wrap
} : getElementNObjLoc(wrap)
});
}
} else if (normalIpt) {
formatted = input.map(function (item) {
var locs = item.locs,
wrap = item.wrap,
subs = item.subs,
otherOpts = _objectWithoutPropertiesLoose(item, _excluded2);
var res = _extends({
locs: formatIpt(locs)[0].locs,
wrap: Array.isArray(wrap) ? {
loc: wrap,
id: wrap
} : getElementNObjLoc(wrap)
}, otherOpts);
if (subs) {
Object.assign(res, {
subs: formatIpt(subs)
});
}
return res;
});
}
return formatted;
}
function genUserX(rawX, firstInWrap) {
var x = new Map();
rawX.forEach(function (val, key) {
var up = val.up,
right = val.right,
down = val.down,
left = val.left,
nextWrap = val.nextWrap,
nextSubWrap = val.nextSubWrap;
var upWrap = nextWrap.up,
rWrap = nextWrap.right,
downWrap = nextWrap.down,
lWrap = nextWrap.left;
var upSubW = nextSubWrap.up,
rSubW = nextSubWrap.right,
dSubWrap = nextSubWrap.down,
lSubW = nextSubWrap.left;
var userUp = genUserDirX("up", up, upWrap, upSubW, rawX, firstInWrap);
var userRight = genUserDirX("right", right, rWrap, rSubW, rawX, firstInWrap);
var userDown = genUserDirX("down", down, downWrap, dSubWrap, rawX, firstInWrap);
var userLeft = genUserDirX("left", left, lWrap, lSubW, rawX, firstInWrap);
x.set(key, {
up: userUp,
right: userRight,
down: userDown,
left: userLeft
});
});
return x;
}
function genUserDirX(dirStr, rawDirX, wrap, subW, rawX, firstInWrap) {
var userDir = rawDirX;
if (rawDirX && wrap) {
// 是否指向包裹层
var wrapTarget = rawX.get(rawDirX.id);
var nextSubWrap = wrapTarget.nextSubWrap;
userDir = wrapTarget[dirStr];
if (nextSubWrap[dirStr]) {
userDir = firstInWrap.get(wrapTarget[dirStr].id);
}
} else if (subW) {
// 是否指向子包裹层
userDir = firstInWrap.get(rawDirX.id);
}
if (userDir == null) return userDir;
var _userDir = userDir;
_userDir.e;
var cleanUsrDirX = _objectWithoutPropertiesLoose(_userDir, _excluded3);
return cleanUsrDirX;
}
function getElementNObjLoc(o) {
if (istanceofHtmlElement(o)) return getElementObjLoc2(o);
if (istanceofHtmlElement(o.loc)) {
return _extends({}, o, {
loc: getElementAryLoc(o.loc),
e: o.loc
});
}
return o;
}
function getElementObjLoc2(e) {
return {
id: e,
loc: getElementAryLoc(e),
e: e
};
}
function getElementAryLoc(e) {
var t = e.getBoundingClientRect();
var x = t.x,
y = t.y,
width = t.width,
height = t.height;
var halfW = width / 2;
var halfH = height / 2;
return [x + halfW, -y - halfH, halfW, halfH];
}
function istanceofHtmlElement(o) {
// return false;
return o instanceof HTMLElement;
}
/**
* 更新矩形引用的位置信息
* @param {any} id
* @param {Map} rawX
* @param {Array<{id: any, loc: number[]}>|Map} newX
*/
function updateRawXByScroll(rawX, newX) {
var mapNewX = newX instanceof Map ? newX : newX.reduce(function (acc, _ref9) {
var id = _ref9.id,
loc = _ref9.loc;
return acc.set(id, loc);
}, new Map());
for (var _iterator5 = _createForOfIteratorHelperLoose(mapNewX), _step5; !(_step5 = _iterator5()).done;) {
var _step5$value = _step5.value,
id = _step5$value[0],
loc = _step5$value[1];
var xInfo = rawX.get(id);
if (xInfo) xInfo.origin.loc = loc;
}
}
function isVisualElement(e, wrap) {
var x = e[0],
y = e[1],
a = e[2],
b = e[3];
var x2 = wrap[0],
y2 = wrap[1],
a2 = wrap[2],
b2 = wrap[3];
return x + a <= x2 + a2 && y + b <= y2 + b2 && x - a >= x2 - a2 && y - b >= y2 - b2;
}
function mergeMap(a, b) {
for (var _iterator6 = _createForOfIteratorHelperLoose(b), _step6; !(_step6 = _iterator6()).done;) {
var _step6$value = _step6.value,
key = _step6$value[0],
val = _step6$value[1];
a.set(key, val);
}
}
module.exports = naviix;
//# sourceMappingURL=naviix.js.map