Browse Source

KERNEL-14012 feat: core/structure文件夹

es6
zsmj 2 years ago
parent
commit
bceffd1a0a
  1. 4036
      src/core/structure/aes.js
  2. 103
      src/core/structure/aspect.js
  3. 216
      src/core/structure/base64.js
  4. 47
      src/core/structure/cache.js
  5. 212
      src/core/structure/cellSizeAndPositionManager.js
  6. 168
      src/core/structure/heap.js
  7. 44
      src/core/structure/index.js
  8. 116
      src/core/structure/linkedHashMap.js
  9. 38
      src/core/structure/lru.js
  10. 291
      src/core/structure/prefixIntervalTree.js
  11. 143
      src/core/structure/queue.js
  12. 121
      src/core/structure/sectionManager.js
  13. 934
      src/core/structure/tree.js
  14. 61
      src/core/structure/vector.js

4036
src/core/structure/aes.js

File diff suppressed because it is too large Load Diff

103
src/core/structure/aspect.js

@ -1,63 +1,58 @@
!(function () { function _aspect(type) {
function aspect (type) { return function (target, methodName, advice) {
return function (target, methodName, advice) { let exist = target[methodName],
var exist = target[methodName], dispatcher;
dispatcher;
if (!exist || exist.target != target) {
if (!exist || exist.target != target) { dispatcher = target[methodName] = function () {
dispatcher = target[methodName] = function () { // before methods
// before methods let beforeArr = dispatcher.before;
var beforeArr = dispatcher.before; let args = arguments, next;
var args = arguments, next; for (let l = beforeArr.length; l--;) {
for (var l = beforeArr.length; l--;) { next = beforeArr[l].advice.apply(this, args);
next = beforeArr[l].advice.apply(this, args); if (next === false) {
if (next === false) { return false;
return false;
}
args = next || args;
}
// target method
var rs = dispatcher.method.apply(this, args);
// after methods
var afterArr = dispatcher.after;
for (var i = 0, ii = afterArr.length; i < ii; i++) {
next = afterArr[i].advice.call(this, rs, args);
if (rs === false) {
return false;
}
args = next || args;
} }
return rs; args = next || args;
};
dispatcher.before = [];
dispatcher.after = [];
if (exist) {
dispatcher.method = exist;
} }
dispatcher.target = target; // target method
} let rs = dispatcher.method.apply(this, args);
// after methods
var aspectArr = (dispatcher || exist)[type]; let afterArr = dispatcher.after;
var obj = { for (let i = 0, ii = afterArr.length; i < ii; i++) {
advice: advice, next = afterArr[i].advice.call(this, rs, args);
_index: aspectArr.length, if (rs === false) {
remove: function () { return false;
aspectArr.splice(this._index, 1); }
args = next || args;
} }
return rs;
}; };
aspectArr.push(obj);
return obj; dispatcher.before = [];
dispatcher.after = [];
if (exist) {
dispatcher.method = exist;
}
dispatcher.target = target;
}
let aspectArr = (dispatcher || exist)[type];
let obj = {
advice: advice,
_index: aspectArr.length,
remove: function () {
aspectArr.splice(this._index, 1);
},
}; };
} aspectArr.push(obj);
BI.aspect = { return obj;
before: aspect("before"),
after: aspect("after")
}; };
}
return BI.aspect; export const aspect = {
before: _aspect("before"),
})(); after: _aspect("after"),
};

216
src/core/structure/base64.js

@ -1,130 +1,132 @@
const _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
!(function () {
var _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; // private method for UTF-8 encoding
const _utf8_encode = function (string) {
string = string.replace(/\r\n/g, "\n");
let utftext = "";
for (let n = 0; n < string.length; n++) {
// private method for UTF-8 encoding const c = string.charCodeAt(n);
var _utf8_encode = function (string) {
string = string.replace(/\r\n/g, "\n");
var utftext = "";
for (var n = 0; n < string.length; n++) {
var c = string.charCodeAt(n);
if (c < 128) {
utftext += String.fromCharCode(c);
} else if ((c > 127) && (c < 2048)) {
utftext += String.fromCharCode((c >> 6) | 192);
utftext += String.fromCharCode((c & 63) | 128);
} else {
utftext += String.fromCharCode((c >> 12) | 224);
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
utftext += String.fromCharCode((c & 63) | 128);
}
if (c < 128) {
utftext += String.fromCharCode(c);
} else if ((c > 127) && (c < 2048)) {
utftext += String.fromCharCode((c >> 6) | 192);
utftext += String.fromCharCode((c & 63) | 128);
} else {
utftext += String.fromCharCode((c >> 12) | 224);
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
utftext += String.fromCharCode((c & 63) | 128);
} }
return utftext; }
};
return utftext;
// private method for UTF-8 decoding };
var _utf8_decode = function (utftext) {
var string = ""; // private method for UTF-8 decoding
var i = 0; const _utf8_decode = function (utftext) {
var c = 0, c3 = 0, c2 = 0; let string = "";
let i = 0;
while (i < utftext.length) { let c = 0, c3 = 0, c2 = 0;
c = utftext.charCodeAt(i); while (i < utftext.length) {
if (c < 128) { c = utftext.charCodeAt(i);
string += String.fromCharCode(c);
i++; if (c < 128) {
} else if ((c > 191) && (c < 224)) { string += String.fromCharCode(c);
c2 = utftext.charCodeAt(i + 1); i++;
string += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); } else if ((c > 191) && (c < 224)) {
i += 2; c2 = utftext.charCodeAt(i + 1);
} else { string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
c2 = utftext.charCodeAt(i + 1); i += 2;
c3 = utftext.charCodeAt(i + 2); } else {
string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); c2 = utftext.charCodeAt(i + 1);
i += 3; c3 = utftext.charCodeAt(i + 2);
} string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
i += 3;
} }
return string;
};
BI._.extend(BI, {
encode: function (input) {
var output = "";
var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
var i = 0;
input = _utf8_encode(input);
while (i < input.length) { }
return string;
chr1 = input.charCodeAt(i++); };
chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(i++); /**
* base64 encode
enc1 = chr1 >> 2; * @param input
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); * @returns {string}
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); */
enc4 = chr3 & 63; export function encode(input) {
let output = "";
if (isNaN(chr2)) { let chr1, chr2, chr3, enc1, enc2, enc3, enc4;
enc3 = enc4 = 64; let i = 0;
} else if (isNaN(chr3)) {
enc4 = 64; input = _utf8_encode(input);
}
while (i < input.length) {
chr1 = input.charCodeAt(i++);
chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(i++);
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
}
output = output + _keyStr.charAt(enc1) + _keyStr.charAt(enc2) + _keyStr.charAt(enc3) + _keyStr.charAt(enc4); output = output + _keyStr.charAt(enc1) + _keyStr.charAt(enc2) + _keyStr.charAt(enc3) + _keyStr.charAt(enc4);
} }
return output; return output;
}, }
// public method for decoding /**
decode: function (input) { * base64 decode
var output = ""; * @param input
var chr1, chr2, chr3; * @returns {string}
var enc1, enc2, enc3, enc4; */
var i = 0; export function decode(input) {
let output = "";
let chr1, chr2, chr3;
let enc1, enc2, enc3, enc4;
let i = 0;
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
while (i < input.length) { while (i < input.length) {
enc1 = _keyStr.indexOf(input.charAt(i++)); enc1 = _keyStr.indexOf(input.charAt(i++));
enc2 = _keyStr.indexOf(input.charAt(i++)); enc2 = _keyStr.indexOf(input.charAt(i++));
enc3 = _keyStr.indexOf(input.charAt(i++)); enc3 = _keyStr.indexOf(input.charAt(i++));
enc4 = _keyStr.indexOf(input.charAt(i++)); enc4 = _keyStr.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4); chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4; chr3 = ((enc3 & 3) << 6) | enc4;
output = output + String.fromCharCode(chr1); output = output + String.fromCharCode(chr1);
if (enc3 != 64) { if (enc3 != 64) {
output = output + String.fromCharCode(chr2); output = output + String.fromCharCode(chr2);
} }
if (enc4 != 64) { if (enc4 != 64) {
output = output + String.fromCharCode(chr3); output = output + String.fromCharCode(chr3);
} }
} }
output = _utf8_decode(output); output = _utf8_decode(output);
return output; return output;
} }
});
})();

47
src/core/structure/cache.js

@ -1,43 +1,42 @@
export const Cache = {
BI.Cache = {
_prefix: "bi", _prefix: "bi",
setUsername: function (username) { setUsername: function (username) {
localStorage.setItem(BI.Cache._prefix + ".username", (username + "" || "").toUpperCase()); localStorage.setItem(Cache._prefix + ".username", (username + "" || "").toUpperCase());
}, },
getUsername: function () { getUsername: function () {
return localStorage.getItem(BI.Cache._prefix + ".username") || ""; return localStorage.getItem(Cache._prefix + ".username") || "";
}, },
_getKeyPrefix: function () { _getKeyPrefix: function () {
return BI.Cache.getUsername() + "." + BI.Cache._prefix + "."; return Cache.getUsername() + "." + Cache._prefix + ".";
}, },
_generateKey: function (key) { _generateKey: function (key) {
return BI.Cache._getKeyPrefix() + (key || ""); return Cache._getKeyPrefix() + (key || "");
}, },
getItem: function (key) { getItem: function (key) {
return localStorage.getItem(BI.Cache._generateKey(key)); return localStorage.getItem(Cache._generateKey(key));
}, },
setItem: function (key, value) { setItem: function (key, value) {
localStorage.setItem(BI.Cache._generateKey(key), value); localStorage.setItem(Cache._generateKey(key), value);
}, },
removeItem: function (key) { removeItem: function (key) {
localStorage.removeItem(BI.Cache._generateKey(key)); localStorage.removeItem(Cache._generateKey(key));
}, },
clear: function () { clear: function () {
for (var i = localStorage.length; i >= 0; i--) { for (let i = localStorage.length; i >= 0; i--) {
var key = localStorage.key(i); const key = localStorage.key(i);
if (key) { if (key) {
if (key.indexOf(BI.Cache._getKeyPrefix()) === 0) { if (key.indexOf(Cache._getKeyPrefix()) === 0) {
localStorage.removeItem(key); localStorage.removeItem(key);
} }
} }
} }
}, },
keys: function () { keys: function () {
var result = []; const result = [];
for (var i = localStorage.length; i >= 0; i--) { for (let i = localStorage.length; i >= 0; i--) {
var key = localStorage.key(i); const key = localStorage.key(i);
if (key) { if (key) {
var prefix = BI.Cache._getKeyPrefix(); const prefix = Cache._getKeyPrefix();
if (key.indexOf(prefix) === 0) { if (key.indexOf(prefix) === 0) {
result[result.length] = key.substring(prefix.length); result[result.length] = key.substring(prefix.length);
} }
@ -47,10 +46,10 @@ BI.Cache = {
}, },
addCookie: function (name, value, path, expiresHours) { addCookie: function (name, value, path, expiresHours) {
var cookieString = name + "=" + encodeURI(value); let cookieString = name + "=" + encodeURI(value);
// 判断是否设置过期时间 // 判断是否设置过期时间
if (expiresHours && expiresHours > 0) { if (expiresHours && expiresHours > 0) {
var date = new Date(); const date = new Date();
// expires是标准GMT格式时间,应该使用时间戳作为起始时间 // expires是标准GMT格式时间,应该使用时间戳作为起始时间
date.setTime(date.getTime() + expiresHours * 3600 * 1000); date.setTime(date.getTime() + expiresHours * 3600 * 1000);
cookieString = cookieString + "; expires=" + date.toUTCString(); cookieString = cookieString + "; expires=" + date.toUTCString();
@ -61,17 +60,19 @@ BI.Cache = {
document.cookie = cookieString; document.cookie = cookieString;
}, },
getCookie: function (name) { getCookie: function (name) {
var arr, reg = new RegExp("(^| )" + name + "=([^;]*)(;|$)"); let arr, reg = new RegExp("(^| )" + name + "=([^;]*)(;|$)");
if (arr = document.cookie.match(reg)) {return decodeURI(arr[2]);} if (arr = document.cookie.match(reg)) {
return decodeURI(arr[2]);
}
return null; return null;
}, },
deleteCookie: function (name, path) { deleteCookie: function (name, path) {
var date = new Date(); const date = new Date();
date.setTime(date.getTime() - 10000); date.setTime(date.getTime() - 10000);
var cookieString = name + "=v; expires=" + date.toUTCString(); let cookieString = name + "=v; expires=" + date.toUTCString();
if (path) { if (path) {
cookieString = cookieString + "; path=" + path; cookieString = cookieString + "; path=" + path;
} }
document.cookie = cookieString; document.cookie = cookieString;
} },
}; };

212
src/core/structure/cellSizeAndPositionManager.js

@ -1,40 +1,40 @@
BI.CellSizeAndPositionManager = function (cellCount, cellSizeGetter, estimatedCellSize) { export class CellSizeAndPositionManager {
this._cellSizeGetter = cellSizeGetter;
this._cellCount = cellCount; constructor(cellCount, cellSizeGetter, estimatedCellSize) {
this._estimatedCellSize = estimatedCellSize; this._cellSizeGetter = cellSizeGetter;
this._cellSizeAndPositionData = {};
this._lastMeasuredIndex = -1;
};
BI.CellSizeAndPositionManager.prototype = {
constructor: BI.CellSizeAndPositionManager,
configure: function (cellCount, estimatedCellSize) {
this._cellCount = cellCount; this._cellCount = cellCount;
this._estimatedCellSize = estimatedCellSize; this._estimatedCellSize = estimatedCellSize;
}, this._cellSizeAndPositionData = {};
this._lastMeasuredIndex = -1;
}
getCellCount: function () { configure(cellCount, estimatedCellSize) {
this._cellCount = cellCount;
this._estimatedCellSize = estimatedCellSize;
}
getCellCount() {
return this._cellCount; return this._cellCount;
}, }
getEstimatedCellSize: function () { getEstimatedCellSize() {
return this._estimatedCellSize; return this._estimatedCellSize;
}, }
getLastMeasuredIndex: function () { getLastMeasuredIndex() {
return this._lastMeasuredIndex; return this._lastMeasuredIndex;
}, }
getSizeAndPositionOfCell: function (index) { getSizeAndPositionOfCell(index) {
if (index < 0 || index >= this._cellCount) { if (index < 0 || index >= this._cellCount) {
return; return;
} }
if (index > this._lastMeasuredIndex) { if (index > this._lastMeasuredIndex) {
var lastMeasuredCellSizeAndPosition = this.getSizeAndPositionOfLastMeasuredCell(); const lastMeasuredCellSizeAndPosition = this.getSizeAndPositionOfLastMeasuredCell();
var offset = lastMeasuredCellSizeAndPosition.offset + lastMeasuredCellSizeAndPosition.size; let offset = lastMeasuredCellSizeAndPosition.offset + lastMeasuredCellSizeAndPosition.size;
for (var i = this._lastMeasuredIndex + 1; i <= index; i++) { for (let i = this._lastMeasuredIndex + 1; i <= index; i++) {
var size = this._cellSizeGetter(i); const size = this._cellSizeGetter(i);
if (size == null || isNaN(size)) { if (size == null || isNaN(size)) {
continue; continue;
@ -42,7 +42,7 @@ BI.CellSizeAndPositionManager.prototype = {
this._cellSizeAndPositionData[i] = { this._cellSizeAndPositionData[i] = {
offset: offset, offset: offset,
size: size size: size,
}; };
offset += size; offset += size;
@ -51,28 +51,28 @@ BI.CellSizeAndPositionManager.prototype = {
this._lastMeasuredIndex = index; this._lastMeasuredIndex = index;
} }
return this._cellSizeAndPositionData[index]; return this._cellSizeAndPositionData[index];
}, }
getSizeAndPositionOfLastMeasuredCell: function () { getSizeAndPositionOfLastMeasuredCell() {
return this._lastMeasuredIndex >= 0 return this._lastMeasuredIndex >= 0
? this._cellSizeAndPositionData[this._lastMeasuredIndex] ? this._cellSizeAndPositionData[this._lastMeasuredIndex]
: { : {
offset: 0, offset: 0,
size: 0 size: 0,
}; };
}, }
getTotalSize: function () { getTotalSize() {
var lastMeasuredCellSizeAndPosition = this.getSizeAndPositionOfLastMeasuredCell(); const lastMeasuredCellSizeAndPosition = this.getSizeAndPositionOfLastMeasuredCell();
return lastMeasuredCellSizeAndPosition.offset + lastMeasuredCellSizeAndPosition.size + (this._cellCount - this._lastMeasuredIndex - 1) * this._estimatedCellSize; return lastMeasuredCellSizeAndPosition.offset + lastMeasuredCellSizeAndPosition.size + (this._cellCount - this._lastMeasuredIndex - 1) * this._estimatedCellSize;
}, }
getUpdatedOffsetForIndex: function (align, containerSize, currentOffset, targetIndex) { getUpdatedOffsetForIndex(align, containerSize, currentOffset, targetIndex) {
var datum = this.getSizeAndPositionOfCell(targetIndex); const datum = this.getSizeAndPositionOfCell(targetIndex);
var maxOffset = datum.offset; const maxOffset = datum.offset;
var minOffset = maxOffset - containerSize + datum.size; const minOffset = maxOffset - containerSize + datum.size;
var idealOffset; let idealOffset;
switch (align) { switch (align) {
case "start": case "start":
@ -89,25 +89,25 @@ BI.CellSizeAndPositionManager.prototype = {
break; break;
} }
var totalSize = this.getTotalSize(); const totalSize = this.getTotalSize();
return Math.max(0, Math.min(totalSize - containerSize, idealOffset)); return Math.max(0, Math.min(totalSize - containerSize, idealOffset));
}, }
getVisibleCellRange: function (containerSize, offset) { getVisibleCellRange(containerSize, offset) {
var totalSize = this.getTotalSize(); const totalSize = this.getTotalSize();
if (totalSize === 0) { if (totalSize === 0) {
return {}; return {};
} }
var maxOffset = offset + containerSize; const maxOffset = offset + containerSize;
var start = this._findNearestCell(offset); const start = this._findNearestCell(offset);
var datum = this.getSizeAndPositionOfCell(start); const datum = this.getSizeAndPositionOfCell(start);
offset = datum.offset + datum.size; offset = datum.offset + datum.size;
var stop = start; let stop = start;
while (offset < maxOffset && stop < this._cellCount - 1) { while (offset < maxOffset && stop < this._cellCount - 1) {
stop++; stop++;
@ -116,17 +116,17 @@ BI.CellSizeAndPositionManager.prototype = {
return { return {
start: start, start: start,
stop: stop stop: stop,
}; };
}, }
resetCell: function (index) { resetCell(index) {
this._lastMeasuredIndex = Math.min(this._lastMeasuredIndex, index - 1); this._lastMeasuredIndex = Math.min(this._lastMeasuredIndex, index - 1);
}, }
_binarySearch: function (high, low, offset) { _binarySearch(high, low, offset) {
var middle; let middle;
var currentOffset; let currentOffset;
while (low <= high) { while (low <= high) {
middle = low + Math.floor((high - low) / 2); middle = low + Math.floor((high - low) / 2);
@ -144,10 +144,10 @@ BI.CellSizeAndPositionManager.prototype = {
if (low > 0) { if (low > 0) {
return low - 1; return low - 1;
} }
}, }
_exponentialSearch: function (index, offset) { _exponentialSearch(index, offset) {
var interval = 1; let interval = 1;
while (index < this._cellCount && this.getSizeAndPositionOfCell(index).offset < offset) { while (index < this._cellCount && this.getSizeAndPositionOfCell(index).offset < offset) {
index += interval; index += interval;
@ -155,117 +155,115 @@ BI.CellSizeAndPositionManager.prototype = {
} }
return this._binarySearch(Math.min(index, this._cellCount - 1), Math.floor(index / 2), offset); return this._binarySearch(Math.min(index, this._cellCount - 1), Math.floor(index / 2), offset);
}, }
_findNearestCell: function (offset) { _findNearestCell(offset) {
if (isNaN(offset)) { if (isNaN(offset)) {
return; return;
} }
offset = Math.max(0, offset); offset = Math.max(0, offset);
var lastMeasuredCellSizeAndPosition = this.getSizeAndPositionOfLastMeasuredCell(); const lastMeasuredCellSizeAndPosition = this.getSizeAndPositionOfLastMeasuredCell();
var lastMeasuredIndex = Math.max(0, this._lastMeasuredIndex); const lastMeasuredIndex = Math.max(0, this._lastMeasuredIndex);
if (lastMeasuredCellSizeAndPosition.offset >= offset) { if (lastMeasuredCellSizeAndPosition.offset >= offset) {
return this._binarySearch(lastMeasuredIndex, 0, offset); return this._binarySearch(lastMeasuredIndex, 0, offset);
} }
return this._exponentialSearch(lastMeasuredIndex, offset); return this._exponentialSearch(lastMeasuredIndex, offset);
}
};
BI.ScalingCellSizeAndPositionManager = function (cellCount, cellSizeGetter, estimatedCellSize, maxScrollSize) { }
this._cellSizeAndPositionManager = new BI.CellSizeAndPositionManager(cellCount, cellSizeGetter, estimatedCellSize); }
this._maxScrollSize = maxScrollSize || 10000000;
};
BI.ScalingCellSizeAndPositionManager.prototype = { export class ScalingCellSizeAndPositionManager {
constructor: BI.ScalingCellSizeAndPositionManager, constructor(cellCount, cellSizeGetter, estimatedCellSize, maxScrollSize) {
this._cellSizeAndPositionManager = new CellSizeAndPositionManager(cellCount, cellSizeGetter, estimatedCellSize);
this._maxScrollSize = maxScrollSize || 10000000;
}
configure: function () { configure() {
this._cellSizeAndPositionManager.configure.apply(this._cellSizeAndPositionManager, arguments); this._cellSizeAndPositionManager.configure.apply(this._cellSizeAndPositionManager, arguments);
}, }
getCellCount: function () { getCellCount() {
return this._cellSizeAndPositionManager.getCellCount(); return this._cellSizeAndPositionManager.getCellCount();
}, }
getEstimatedCellSize: function () { getEstimatedCellSize() {
return this._cellSizeAndPositionManager.getEstimatedCellSize(); return this._cellSizeAndPositionManager.getEstimatedCellSize();
}, }
getLastMeasuredIndex: function () { getLastMeasuredIndex() {
return this._cellSizeAndPositionManager.getLastMeasuredIndex(); return this._cellSizeAndPositionManager.getLastMeasuredIndex();
}, }
getOffsetAdjustment: function (containerSize, offset) { getOffsetAdjustment(containerSize, offset) {
var totalSize = this._cellSizeAndPositionManager.getTotalSize(); const totalSize = this._cellSizeAndPositionManager.getTotalSize();
var safeTotalSize = this.getTotalSize(); const safeTotalSize = this.getTotalSize();
var offsetPercentage = this._getOffsetPercentage(containerSize, offset, safeTotalSize); const offsetPercentage = this._getOffsetPercentage(containerSize, offset, safeTotalSize);
return Math.round(offsetPercentage * (safeTotalSize - totalSize)); return Math.round(offsetPercentage * (safeTotalSize - totalSize));
}, }
getSizeAndPositionOfCell: function (index) { getSizeAndPositionOfCell(index) {
return this._cellSizeAndPositionManager.getSizeAndPositionOfCell(index); return this._cellSizeAndPositionManager.getSizeAndPositionOfCell(index);
}, }
getSizeAndPositionOfLastMeasuredCell: function () { getSizeAndPositionOfLastMeasuredCell() {
return this._cellSizeAndPositionManager.getSizeAndPositionOfLastMeasuredCell(); return this._cellSizeAndPositionManager.getSizeAndPositionOfLastMeasuredCell();
}, }
getTotalSize: function () { getTotalSize() {
return Math.min(this._maxScrollSize, this._cellSizeAndPositionManager.getTotalSize()); return Math.min(this._maxScrollSize, this._cellSizeAndPositionManager.getTotalSize());
}, }
getUpdatedOffsetForIndex: function (align, containerSize, currentOffset, targetIndex) { getUpdatedOffsetForIndex(align, containerSize, currentOffset, targetIndex) {
currentOffset = this._safeOffsetToOffset(containerSize, currentOffset); currentOffset = this._safeOffsetToOffset(containerSize, currentOffset);
var offset = this._cellSizeAndPositionManager.getUpdatedOffsetForIndex(align, containerSize, currentOffset, targetIndex); const offset = this._cellSizeAndPositionManager.getUpdatedOffsetForIndex(align, containerSize, currentOffset, targetIndex);
return this._offsetToSafeOffset(containerSize, offset); return this._offsetToSafeOffset(containerSize, offset);
}, }
getVisibleCellRange: function (containerSize, offset) { getVisibleCellRange(containerSize, offset) {
offset = this._safeOffsetToOffset(containerSize, offset); offset = this._safeOffsetToOffset(containerSize, offset);
return this._cellSizeAndPositionManager.getVisibleCellRange(containerSize, offset); return this._cellSizeAndPositionManager.getVisibleCellRange(containerSize, offset);
}, }
resetCell: function (index) { resetCell(index) {
this._cellSizeAndPositionManager.resetCell(index); this._cellSizeAndPositionManager.resetCell(index);
}, }
_getOffsetPercentage: function (containerSize, offset, totalSize) { _getOffsetPercentage(containerSize, offset, totalSize) {
return totalSize <= containerSize return totalSize <= containerSize
? 0 ? 0
: offset / (totalSize - containerSize); : offset / (totalSize - containerSize);
}, }
_offsetToSafeOffset: function (containerSize, offset) { _offsetToSafeOffset(containerSize, offset) {
var totalSize = this._cellSizeAndPositionManager.getTotalSize(); const totalSize = this._cellSizeAndPositionManager.getTotalSize();
var safeTotalSize = this.getTotalSize(); const safeTotalSize = this.getTotalSize();
if (totalSize === safeTotalSize) { if (totalSize === safeTotalSize) {
return offset; return offset;
} }
var offsetPercentage = this._getOffsetPercentage(containerSize, offset, totalSize); const offsetPercentage = this._getOffsetPercentage(containerSize, offset, totalSize);
return Math.round(offsetPercentage * (safeTotalSize - containerSize)); return Math.round(offsetPercentage * (safeTotalSize - containerSize));
},
_safeOffsetToOffset: function (containerSize, offset) { }
var totalSize = this._cellSizeAndPositionManager.getTotalSize();
var safeTotalSize = this.getTotalSize(); _safeOffsetToOffset(containerSize, offset) {
const totalSize = this._cellSizeAndPositionManager.getTotalSize();
const safeTotalSize = this.getTotalSize();
if (totalSize === safeTotalSize) { if (totalSize === safeTotalSize) {
return offset; return offset;
} }
var offsetPercentage = this._getOffsetPercentage(containerSize, offset, safeTotalSize); const offsetPercentage = this._getOffsetPercentage(containerSize, offset, safeTotalSize);
return Math.round(offsetPercentage * (totalSize - containerSize)); return Math.round(offsetPercentage * (totalSize - containerSize));
} }
}; }

168
src/core/structure/heap.js

@ -1,115 +1,111 @@
function defaultComparator(a, b) {
return a < b;
}
(function () { export class Heap {
function defaultComparator (a, b) { constructor(items, comparator) {
return a < b;
}
BI.Heap = function (items, comparator) {
this._items = items || []; this._items = items || [];
this._size = this._items.length; this._size = this._items.length;
this._comparator = comparator || defaultComparator; this._comparator = comparator || defaultComparator;
this._heapify(); this._heapify();
}; }
BI.Heap.prototype = {
constructor: BI.Heap,
empty: function () {
return this._size === 0;
},
pop: function () { empty() {
if (this._size === 0) { return this._size === 0;
return; }
}
var elt = this._items[0]; pop() {
if (this._size === 0) {
return;
}
var lastElt = this._items.pop(); const elt = this._items[0];
this._size--;
if (this._size > 0) { const lastElt = this._items.pop();
this._items[0] = lastElt; this._size--;
this._sinkDown(0);
}
return elt; if (this._size > 0) {
}, this._items[0] = lastElt;
this._sinkDown(0);
}
push: function (item) { return elt;
this._items[this._size++] = item; }
this._bubbleUp(this._size - 1);
},
size: function () { push(item) {
return this._size; this._items[this._size++] = item;
}, this._bubbleUp(this._size - 1);
}
peek: function () { size() {
if (this._size === 0) { return this._size;
return; }
}
return this._items[0]; peek() {
}, if (this._size === 0) {
return;
}
_heapify: function () { return this._items[0];
for (var index = Math.floor((this._size + 1) / 2); index >= 0; index--) { }
this._sinkDown(index);
}
},
_bubbleUp: function (index) { _heapify() {
var elt = this._items[index]; for (let index = Math.floor((this._size + 1) / 2); index >= 0; index--) {
while (index > 0) { this._sinkDown(index);
var parentIndex = Math.floor((index + 1) / 2) - 1; }
var parentElt = this._items[parentIndex]; }
// if parentElt < elt, stop _bubbleUp(index) {
if (this._comparator(parentElt, elt)) { const elt = this._items[index];
return; while (index > 0) {
} const parentIndex = Math.floor((index + 1) / 2) - 1;
const parentElt = this._items[parentIndex];
// swap // if parentElt < elt, stop
this._items[parentIndex] = elt; if (this._comparator(parentElt, elt)) {
this._items[index] = parentElt; return;
index = parentIndex;
} }
},
_sinkDown: function (index) { // swap
var elt = this._items[index]; this._items[parentIndex] = elt;
this._items[index] = parentElt;
index = parentIndex;
}
}
while (true) { _sinkDown(index) {
var leftChildIndex = 2 * (index + 1) - 1; const elt = this._items[index];
var rightChildIndex = 2 * (index + 1);
var swapIndex = -1;
if (leftChildIndex < this._size) { while (true) {
var leftChild = this._items[leftChildIndex]; const leftChildIndex = 2 * (index + 1) - 1;
if (this._comparator(leftChild, elt)) { const rightChildIndex = 2 * (index + 1);
swapIndex = leftChildIndex; let swapIndex = -1;
}
}
if (rightChildIndex < this._size) { if (leftChildIndex < this._size) {
var rightChild = this._items[rightChildIndex]; const leftChild = this._items[leftChildIndex];
if (this._comparator(rightChild, elt)) { if (this._comparator(leftChild, elt)) {
if (swapIndex === -1 || swapIndex = leftChildIndex;
this._comparator(rightChild, this._items[swapIndex])) {
swapIndex = rightChildIndex;
}
}
} }
}
// if we don't have a swap, stop if (rightChildIndex < this._size) {
if (swapIndex === -1) { const rightChild = this._items[rightChildIndex];
return; if (this._comparator(rightChild, elt)) {
if (swapIndex === -1 ||
this._comparator(rightChild, this._items[swapIndex])) {
swapIndex = rightChildIndex;
}
} }
}
this._items[index] = this._items[swapIndex]; // if we don't have a swap, stop
this._items[swapIndex] = elt; if (swapIndex === -1) {
index = swapIndex; return;
} }
this._items[index] = this._items[swapIndex];
this._items[swapIndex] = elt;
index = swapIndex;
} }
}; }
})(); }

44
src/core/structure/index.js

@ -0,0 +1,44 @@
import * as a1 from "./aes";
import * as a2 from "./aspect";
import * as a3 from "./base64";
import * as a4 from "./cache";
import * as a5 from "./cellSizeAndPositionManager";
import * as a6 from "./heap";
import * as a7 from "./linkedHashMap";
import * as a8 from "./lru";
import * as a9 from "./prefixIntervalTree";
import * as a10 from "./queue";
import * as a11 from "./sectionManager";
import * as a12 from "./tree";
import * as a13 from "./vector";
Object.assign(BI, {
...a1,
...a2,
...a3,
...a4,
...a5,
...a6,
...a7,
...a8,
...a9,
...a10,
...a11,
...a12,
...a13,
});
export * from "./aes";
export * from "./aspect";
export * from "./base64";
export * from "./cache";
export * from "./cellSizeAndPositionManager";
export * from "./heap";
export * from "./linkedHashMap";
export * from "./lru";
export * from "./prefixIntervalTree";
export * from "./queue";
export * from "./sectionManager";
export * from "./tree";
export * from "./vector";

116
src/core/structure/linkedHashMap.js

@ -1,72 +1,66 @@
export class LinkHashMap {
!(function () { constructor() {
BI.LinkHashMap = function () {
this.array = []; this.array = [];
this.map = {}; this.map = {};
}; }
BI.LinkHashMap.prototype = {
constructor: BI.LinkHashMap,
has: function (key) {
if (key in this.map) {
return true;
}
return false;
},
add: function (key, value) {
if (typeof key === "undefined") {
return;
}
if (key in this.map) {
this.map[key] = value;
} else {
this.array.push(key);
this.map[key] = value;
}
},
remove: function (key) { has(key) {
if (key in this.map) { return key in this.map;
delete this.map[key]; }
for (var i = 0; i < this.array.length; i++) {
if (this.array[i] == key) {
this.array.splice(i, 1);
break;
}
}
}
},
size: function () { add(key, value) {
return this.array.length; if (typeof key === "undefined") {
}, return;
}
if (key in this.map) {
this.map[key] = value;
} else {
this.array.push(key);
this.map[key] = value;
}
}
each: function (fn, scope) { remove(key) {
var scope = scope || window; if (key in this.map) {
var fn = fn || null; delete this.map[key];
if (fn == null || typeof (fn) !== "function") { for (let i = 0; i < this.array.length; i++) {
return; if (this.array[i] == key) {
} this.array.splice(i, 1);
for (var i = 0; i < this.array.length; i++) {
var key = this.array[i];
var value = this.map[key];
var re = fn.call(scope, key, value, i, this.array, this.map);
if (re == false) {
break; break;
} }
} }
}, }
}
get: function (key) { size() {
return this.map[key]; return this.array.length;
}, }
toArray: function () { each(fn, scope) {
var array = []; scope = scope || window;
this.each(function (key, value) { fn = fn || null;
array.push(value); if (fn == null || typeof (fn) !== "function") {
}); return;
return array;
} }
}; for (let i = 0; i < this.array.length; i++) {
})(); const key = this.array[i];
const value = this.map[key];
const re = fn.call(scope, key, value, i, this.array, this.map);
if (re == false) {
break;
}
}
}
get(key) {
return this.map[key];
}
toArray() {
const array = [];
this.each(function (key, value) {
array.push(value);
});
return array;
}
}

38
src/core/structure/lru.js

@ -1,24 +1,21 @@
export class LRU {
!(function () { constructor(limit) {
BI.LRU = function (limit) {
this.size = 0; this.size = 0;
this.limit = limit; this.limit = limit;
this.head = this.tail = undefined; this.head = this.tail = undefined;
this._keymap = {}; this._keymap = {};
}; }
var p = BI.LRU.prototype;
p.put = function (key, value) { put(key, value) {
var removed; let removed;
if (this.size === this.limit) { if (this.size === this.limit) {
removed = this.shift(); removed = this.shift();
} }
var entry = this.get(key, true); let entry = this.get(key, true);
if (!entry) { if (!entry) {
entry = { entry = {
key: key key: key,
}; };
this._keymap[key] = entry; this._keymap[key] = entry;
if (this.tail) { if (this.tail) {
@ -33,10 +30,10 @@
entry.value = value; entry.value = value;
return removed; return removed;
}; }
p.shift = function () { shift() {
var entry = this.head; const entry = this.head;
if (entry) { if (entry) {
this.head = this.head.newer; this.head = this.head.newer;
this.head.older = undefined; this.head.older = undefined;
@ -45,11 +42,10 @@
this.size--; this.size--;
} }
return entry; return entry;
}; }
p.get = function (key, returnEntry) { get(key, returnEntry) {
var entry = this._keymap[key]; const entry = this._keymap[key];
if (entry === undefined) return; if (entry === undefined) return;
if (entry === this.tail) { if (entry === this.tail) {
return returnEntry return returnEntry
@ -78,9 +74,9 @@
return returnEntry return returnEntry
? entry ? entry
: entry.value; : entry.value;
}; }
p.has = function (key) { has(key) {
return this._keymap[key] != null; return this._keymap[key] != null;
}; }
})(); }

291
src/core/structure/prefixIntervalTree.js

@ -1,32 +1,32 @@
// 线段树 // 线段树
(function () { const parent = function (node) {
var parent = function (node) { return Math.floor(node / 2);
return Math.floor(node / 2); };
};
const Int32Array = _global.Int32Array || function (size) {
var Int32Array = _global.Int32Array || function (size) { const xs = [];
var xs = []; for (let i = size - 1; i >= 0; --i) {
for (var i = size - 1; i >= 0; --i) { xs[i] = 0;
xs[i] = 0; }
} return xs;
return xs; };
};
const ceilLog2 = function (x) {
var ceilLog2 = function (x) { let y = 1;
var y = 1; while (y < x) {
while (y < x) { y *= 2;
y *= 2; }
} return y;
return y; };
};
export class PrefixIntervalTree {
BI.PrefixIntervalTree = function (xs) { constructor(xs) {
this._size = xs.length; this._size = xs.length;
this._half = ceilLog2(this._size); this._half = ceilLog2(this._size);
// _heap是一个_size两倍以上的堆 // _heap是一个_size两倍以上的堆
this._heap = new Int32Array(2 * this._half); this._heap = new Int32Array(2 * this._half);
var i; let i;
// 初始化 >= _size 的堆空间, 即叶子节点 // 初始化 >= _size 的堆空间, 即叶子节点
for (i = 0; i < this._size; ++i) { for (i = 0; i < this._size; ++i) {
this._heap[this._half + i] = xs[i]; this._heap[this._half + i] = xs[i];
@ -35,146 +35,143 @@
for (i = this._half - 1; i > 0; --i) { for (i = this._half - 1; i > 0; --i) {
this._heap[i] = this._heap[2 * i] + this._heap[2 * i + 1]; this._heap[i] = this._heap[2 * i] + this._heap[2 * i + 1];
} }
}; }
BI.PrefixIntervalTree.prototype = {
constructor: BI.PrefixIntervalTree,
// 往_half之后的空间set值,需要更新其所有祖先节点的值
set: function (index, value) {
var node = this._half + index;
this._heap[node] = value;
node = parent(node);
for (; node !== 0; node = parent(node)) {
this._heap[node] =
this._heap[2 * node] + this._heap[2 * node + 1];
}
},
get: function (index) { static uniform(size, initialValue) {
var node = this._half + index; const xs = [];
return this._heap[node]; for (let i = size - 1; i >= 0; --i) {
}, xs[i] = initialValue;
}
getSize: function () { return new PrefixIntervalTree(xs);
return this._size; }
},
/**
* get(0) + get(1) + ... + get(end - 1).
*/
sumUntil: function (end) {
if (end === 0) {
return 0;
}
var node = this._half + end - 1; static empty(size) {
var sum = this._heap[node]; return PrefixIntervalTree.uniform(size, 0);
for (; node !== 1; node = parent(node)) { }
if (node % 2 === 1) {
sum += this._heap[node - 1];
}
}
return sum; set(index, value) {
}, let node = this._half + index;
this._heap[node] = value;
/**
* get(0) + get(1) + ... + get(inclusiveEnd).
*/
sumTo: function (inclusiveEnd) {
return this.sumUntil(inclusiveEnd + 1);
},
/**
* sum get(begin) + get(begin + 1) + ... + get(end - 1).
*/
sum: function (begin, end) {
return this.sumUntil(end) - this.sumUntil(begin);
},
/**
* Returns the smallest i such that 0 <= i <= size and sumUntil(i) <= t, or
* -1 if no such i exists.
*/
greatestLowerBound: function (t) {
if (t < 0) {
return -1;
}
var node = 1; node = parent(node);
if (this._heap[node] <= t) { for (; node !== 0; node = parent(node)) {
return this._size; this._heap[node] =
} this._heap[2 * node] + this._heap[2 * node + 1];
}
}
get(index) {
const node = this._half + index;
return this._heap[node];
}
getSize() {
return this._size;
}
/**
* get(0) + get(1) + ... + get(end - 1).
*/
sumUntil(end) {
if (end === 0) {
return 0;
}
while (node < this._half) { let node = this._half + end - 1;
var leftSum = this._heap[2 * node]; let sum = this._heap[node];
if (t < leftSum) { for (; node !== 1; node = parent(node)) {
node = 2 * node; if (node % 2 === 1) {
} else { sum += this._heap[node - 1];
node = 2 * node + 1;
t -= leftSum;
}
} }
}
return node - this._half; return sum;
}, }
/**
* get(0) + get(1) + ... + get(inclusiveEnd).
*/
sumTo(inclusiveEnd) {
return this.sumUntil(inclusiveEnd + 1);
}
/**
* sum get(begin) + get(begin + 1) + ... + get(end - 1).
*/
sum(begin, end) {
return this.sumUntil(end) - this.sumUntil(begin);
}
/**
* Returns the smallest i such that 0 <= i <= size and sumUntil(i) <= t, or
* -1 if no such i exists.
*/
greatestLowerBound(t) {
if (t < 0) {
return -1;
}
/** let node = 1;
* Returns the smallest i such that 0 <= i <= size and sumUntil(i) < t, or if (this._heap[node] <= t) {
* -1 if no such i exists. return this._size;
*/ }
greatestStrictLowerBound: function (t) {
if (t <= 0) {
return -1;
}
var node = 1; while (node < this._half) {
if (this._heap[node] < t) { const leftSum = this._heap[2 * node];
return this._size; if (t < leftSum) {
node = 2 * node;
} else {
node = 2 * node + 1;
t -= leftSum;
} }
}
while (node < this._half) { return node - this._half;
var leftSum = this._heap[2 * node]; }
if (t <= leftSum) {
node = 2 * node;
} else {
node = 2 * node + 1;
t -= leftSum;
}
}
return node - this._half; /**
}, * Returns the smallest i such that 0 <= i <= size and sumUntil(i) < t, or
* -1 if no such i exists.
/** */
* Returns the smallest i such that 0 <= i <= size and t <= sumUntil(i), or greatestStrictLowerBound(t) {
* size + 1 if no such i exists. if (t <= 0) {
*/ return -1;
leastUpperBound: function (t) {
return this.greatestStrictLowerBound(t) + 1;
},
/**
* Returns the smallest i such that 0 <= i <= size and t < sumUntil(i), or
* size + 1 if no such i exists.
*/
leastStrictUpperBound: function (t) {
return this.greatestLowerBound(t) + 1;
} }
};
BI.PrefixIntervalTree.uniform = function (size, initialValue) { let node = 1;
var xs = []; if (this._heap[node] < t) {
for (var i = size - 1; i >= 0; --i) { return this._size;
xs[i] = initialValue;
} }
return new BI.PrefixIntervalTree(xs); while (node < this._half) {
}; const leftSum = this._heap[2 * node];
if (t <= leftSum) {
node = 2 * node;
} else {
node = 2 * node + 1;
t -= leftSum;
}
}
return node - this._half;
}
/**
* Returns the smallest i such that 0 <= i <= size and t <= sumUntil(i), or
* size + 1 if no such i exists.
*/
leastUpperBound(t) {
return this.greatestStrictLowerBound(t) + 1;
}
/**
* Returns the smallest i such that 0 <= i <= size and t < sumUntil(i), or
* size + 1 if no such i exists.
*/
leastStrictUpperBound(t) {
return this.greatestLowerBound(t) + 1;
}
BI.PrefixIntervalTree.empty = function (size) {
return BI.PrefixIntervalTree.uniform(size, 0);
};
})(); }

143
src/core/structure/queue.js

@ -1,89 +1,86 @@
import {contains, remove} from "../2.base";
!(function () { export class Queue {
BI.Queue = function (capacity) { constructor(capacity) {
this.capacity = capacity; this.capacity = capacity;
this.array = []; this.array = [];
}; }
BI.Queue.prototype = {
constructor: BI.Queue,
contains: function (v) {
return BI.contains(this.array, v);
},
indexOf: function (v) {
return BI.contains(this.array, v);
},
getElementByIndex: function (index) {
return this.array[index];
},
push: function (v) {
this.array.push(v);
if (this.capacity && this.array.length > this.capacity) {
this.array.shift();
}
},
pop: function () { contains(v) {
this.array.pop(); return contains(this.array, v);
}, }
indexOf(v) {
return contains(this.array, v);
}
getElementByIndex(index) {
return this.array[index];
}
shift: function () { push(v) {
this.array.push(v);
if (this.capacity && this.array.length > this.capacity) {
this.array.shift(); this.array.shift();
}, }
}
unshift: function (v) { pop() {
this.array.unshift(v); this.array.pop();
if (this.capacity && this.array.length > this.capacity) { }
this.array.pop();
} shift() {
}, this.array.shift();
}
unshift(v) {
this.array.unshift(v);
if (this.capacity && this.array.length > this.capacity) {
this.array.pop();
}
}
remove: function (v) { remove(v) {
BI.remove(this.array, v); remove(this.array, v);
}, }
splice: function () { splice() {
this.array.splice.apply(this.array, arguments); this.array.splice.apply(this.array, arguments);
}, }
slice: function () { slice() {
this.array.slice.apply(this.array, arguments); this.array.slice.apply(this.array, arguments);
}, }
size: function () { size() {
return this.array.length; return this.array.length;
}, }
each: function (fn, scope) { each(fn, scope) {
var scope = scope || window; scope = scope || window;
var fn = fn || null; fn = fn || null;
if (fn == null || typeof (fn) !== "function") { if (fn == null || typeof (fn) !== "function") {
return; return;
} }
for (var i = 0; i < this.array.length; i++) { for (let i = 0; i < this.array.length; i++) {
var re = fn.call(scope, i, this.array[i], this.array); const re = fn.call(scope, i, this.array[i], this.array);
if (re == false) { if (re === false) {
break; break;
}
} }
}, }
}
toArray: function () { toArray() {
return this.array; return this.array;
}, }
fromArray(array) {
array.each(v => this.push(v));
}
clear() {
this.array.length = 0;
}
}
fromArray: function (array) {
var self = this;
BI.each(array, function (i, v) {
self.push(v);
});
},
clear: function () {
this.array.length = 0;
}
};
})();

121
src/core/structure/sectionManager.js

@ -1,5 +1,7 @@
!(function () { import {each, keys, map, size} from "../2.base";
var Section = function (height, width, x, y) {
class Section {
constructor(height, width, x, y) {
this.height = height; this.height = height;
this.width = width; this.width = width;
this.x = x; this.x = x;
@ -7,82 +9,79 @@
this._indexMap = {}; this._indexMap = {};
this._indices = []; this._indices = [];
}; }
Section.prototype = {
constructor: Section,
addCellIndex: function (index) {
if (!this._indexMap[index]) {
this._indexMap[index] = true;
this._indices.push(index);
}
},
getCellIndices: function () { addCellIndex(index) {
return this._indices; if (!this._indexMap[index]) {
this._indexMap[index] = true;
this._indices.push(index);
} }
}; }
getCellIndices() {
return this._indices;
}
}
var SECTION_SIZE = 100; const SECTION_SIZE = 100;
BI.SectionManager = function (sectionSize) {
this._sectionSize = sectionSize || SECTION_SIZE; export class SectionManager {
constructor(sectionSize = SECTION_SIZE) {
this._sectionSize = sectionSize;
this._cellMetadata = []; this._cellMetadata = [];
this._sections = {}; this._sections = {};
}; }
BI.SectionManager.prototype = {
constructor: BI.SectionManager,
getCellIndices: function (height, width, x, y) {
var indices = {};
BI.each(this.getSections(height, width, x, y), function (i, section) { getCellIndices(height, width, x, y) {
BI.each(section.getCellIndices(), function (j, index) { const indices = {};
indices[index] = index;
});
});
return BI.map(BI.keys(indices), function (i, index) { each(this.getSections(height, width, x, y), function (i, section) {
return indices[index]; each(section.getCellIndices(), function (j, index) {
indices[index] = index;
}); });
}, });
getCellMetadata: function (index) { return map(keys(indices), function (i, index) {
return this._cellMetadata[index]; return indices[index];
}, });
}
getSections: function (height, width, x, y) { getCellMetadata(index) {
var sectionXStart = Math.floor(x / this._sectionSize); return this._cellMetadata[index];
var sectionXStop = Math.floor((x + width - 1) / this._sectionSize); }
var sectionYStart = Math.floor(y / this._sectionSize);
var sectionYStop = Math.floor((y + height - 1) / this._sectionSize);
var sections = []; getSections(height, width, x, y) {
const sectionXStart = Math.floor(x / this._sectionSize);
const sectionXStop = Math.floor((x + width - 1) / this._sectionSize);
const sectionYStart = Math.floor(y / this._sectionSize);
const sectionYStop = Math.floor((y + height - 1) / this._sectionSize);
for (var sectionX = sectionXStart; sectionX <= sectionXStop; sectionX++) { const sections = [];
for (var sectionY = sectionYStart; sectionY <= sectionYStop; sectionY++) {
var key = sectionX + "." + sectionY;
if (!this._sections[key]) { for (let sectionX = sectionXStart; sectionX <= sectionXStop; sectionX++) {
this._sections[key] = new Section(this._sectionSize, this._sectionSize, sectionX * this._sectionSize, sectionY * this._sectionSize); for (let sectionY = sectionYStart; sectionY <= sectionYStop; sectionY++) {
} const key = sectionX + "." + sectionY;
sections.push(this._sections[key]); if (!this._sections[key]) {
this._sections[key] = new Section(this._sectionSize, this._sectionSize, sectionX * this._sectionSize, sectionY * this._sectionSize);
} }
sections.push(this._sections[key]);
} }
}
return sections; return sections;
}, }
getTotalSectionCount: function () { getTotalSectionCount() {
return BI.size(this._sections); return size(this._sections);
}, }
registerCell: function (cellMetadatum, index) { registerCell(cellMetadatum, index) {
this._cellMetadata[index] = cellMetadatum; this._cellMetadata[index] = cellMetadatum;
BI.each(this.getSections(cellMetadatum.height, cellMetadatum.width, cellMetadatum.x, cellMetadatum.y), function (i, section) { each(this.getSections(cellMetadatum.height, cellMetadatum.width, cellMetadatum.x, cellMetadatum.y), function (i, section) {
section.addCellIndex(index); section.addCellIndex(index);
}); });
} }
}; }
})();

934
src/core/structure/tree.js

@ -1,517 +1,521 @@
(function () { import {
BI.Tree = function () { isObject,
this.root = new BI.Node(BI.UUID()); UUID,
}; extend,
isEmpty,
BI.Tree.prototype = { isArray,
constructor: BI.Tree, first,
addNode: function (node, newNode, index) { last,
if (BI.isNull(newNode)) { findIndex,
this.root.addChild(node, index); isUndefined,
} else if (BI.isNull(node)) { isNull,
this.root.addChild(newNode, index); each,
} else { deepClone,
node.addChild(newNode, index); isEqual, some, every, clone
} } from "../2.base";
},
export class Node {
isRoot: function (node) { constructor(id) {
return node === this.root; if (isObject(id)) {
}, extend(this, id);
} else {
getRoot: function () { this.id = id;
return this.root; }
}, this.clear();
}
clear: function () {
this.root.clear();
},
initTree: function (nodes) {
var self = this;
this.clear();
var queue = [];
BI.each(nodes, function (i, node) {
var n = new BI.Node(node);
n.set("data", node);
self.addNode(n);
queue.push(n);
});
while (!BI.isEmpty(queue)) {
var parent = queue.shift();
var node = parent.get("data");
BI.each(node.children, function (i, child) {
var n = new BI.Node(child);
n.set("data", child);
queue.push(n);
self.addNode(parent, n);
});
}
},
_toJSON: function (node) { set(key, value) {
var self = this; if (isObject(key)) {
var children = []; extend(this, key);
BI.each(node.getChildren(), function (i, child) { return;
children.push(self._toJSON(child)); }
}); this[key] = value;
return BI.extend({ }
id: node.id
}, BI.deepClone(node.get("data")), (children.length > 0 ? { get(key) {
children: children return this[key];
} : {})); }
},
isLeaf() {
toJSON: function (node) { return isEmpty(this.children);
var self = this, result = []; }
BI.each((node || this.root).getChildren(), function (i, child) {
result.push(self._toJSON(child)); getChildren() {
}); return this.children;
return result; }
},
getChildrenLength() {
_toJSONWithNode: function (node) { return this.children.length;
var self = this; }
var children = [];
BI.each(node.getChildren(), function (i, child) { getFirstChild() {
children.push(self._toJSONWithNode(child)); return first(this.children);
}); }
return BI.extend({
id: node.id getLastChild() {
}, BI.deepClone(node.get("data")), { return last(this.children);
node: node }
}, (children.length > 0 ? {
children: children setLeft(left) {
} : {})); this.left = left;
}, }
toJSONWithNode: function (node) { getLeft() {
var self = this, result = []; return this.left;
BI.each((node || this.root).getChildren(), function (i, child) { }
result.push(self._toJSONWithNode(child));
setRight(right) {
this.right = right;
}
getRight() {
return this.right;
}
setParent(parent) {
this.parent = parent;
}
getParent() {
return this.parent;
}
getChild(index) {
return this.children[index];
}
getChildIndex(id) {
return findIndex(this.children, function (i, ch) {
return ch.get("id") === id;
});
}
removeChild(id) {
this.removeChildByIndex(this.getChildIndex(id));
}
removeChildByIndex(index) {
const before = this.getChild(index - 1);
const behind = this.getChild(index + 1);
if (before != null) {
before.setRight(behind || null);
}
if (behind != null) {
behind.setLeft(before || null);
}
this.children.splice(index, 1);
}
removeAllChilds() {
this.children = [];
}
addChild(child, index) {
let cur = null;
if (isUndefined(index)) {
cur = this.children.length - 1;
} else {
cur = index - 1;
}
child.setParent(this);
if (cur >= 0) {
this.getChild(cur) && this.getChild(cur).setRight(child);
child.setLeft(this.getChild(cur));
}
if (isUndefined(index)) {
this.children.push(child);
} else {
this.children.splice(index, 0, child);
}
}
equals(obj) {
return this === obj || this.id === obj.id;
}
clear() {
this.parent = null;
this.left = null;
this.right = null;
this.children = [];
}
}
export class Tree {
constructor() {
this.root = new Node(UUID());
}
addNode(node, newNode, index) {
if (isNull(newNode)) {
this.root.addChild(node, index);
} else if (isNull(node)) {
this.root.addChild(newNode, index);
} else {
node.addChild(newNode, index);
}
}
isRoot(node) {
return node === this.root;
}
getRoot() {
return this.root;
}
clear() {
this.root.clear();
}
initTree(nodes) {
this.clear();
const queue = [];
each(nodes, (i, node) => {
const n = new Node(node);
n.set("data", node);
this.addNode(n);
queue.push(n);
});
while (!isEmpty(queue)) {
const parent = queue.shift();
const node = parent.get("data");
each(node.children, (i, child) => {
const n = new Node(child);
n.set("data", child);
queue.push(n);
this.addNode(parent, n);
}); });
return result; }
}, }
_toJSON(node) {
const children = [];
each(node.getChildren(), (i, child) => {
children.push(this._toJSON(child));
});
return extend({
id: node.id,
}, deepClone(node.get("data")), (children.length > 0 ? {
children: children,
} : {}));
}
toJSON(node) {
const result = [];
each((node || this.root).getChildren(), (i, child) => {
result.push(this._toJSON(child));
});
return result;
}
_toJSONWithNode(node) {
const children = [];
each(node.getChildren(), (i, child) => {
children.push(this._toJSONWithNode(child));
});
return extend({
id: node.id,
}, deepClone(node.get("data")), {
node: node,
}, (children.length > 0 ? {
children: children,
} : {}));
}
toJSONWithNode(node) {
const result = [];
each((node || this.root).getChildren(), (i, child) => {
result.push(this._toJSONWithNode(child));
});
return result;
}
search(root, target, param) {
if (!(root instanceof Node)) {
return this.search(this.root, root, target);
}
let next = null;
search: function (root, target, param) { if (isNull(target)) {
if (!(root instanceof BI.Node)) { return null;
return arguments.callee.apply(this, [this.root, root, target]); }
if (isEqual(root[param || "id"], target)) {
return root;
}
some(root.getChildren(), (i, child) => {
next = this.search(child, target, param);
if (null !== next) {
return true;
} }
var self = this, next = null; });
return next;
if (BI.isNull(target)) { }
return null;
_traverse(node, callback) {
let queue = [];
queue.push(node);
while (!isEmpty(queue)) {
const temp = queue.shift();
const b = callback && callback(temp);
if (b === false) {
break;
} }
if (BI.isEqual(root[param || "id"], target)) { if (b === true) {
return root; continue;
} }
BI.any(root.getChildren(), function (i, child) { if (temp != null) {
next = self.search(child, target, param); queue = queue.concat(temp.getChildren());
if (null !== next) {
return true;
}
});
return next;
},
_traverse: function (node, callback) {
var queue = [];
queue.push(node);
while (!BI.isEmpty(queue)) {
var temp = queue.shift();
var b = callback && callback(temp);
if (b === false) {
break;
}
if (b === true) {
continue;
}
if (temp != null) {
queue = queue.concat(temp.getChildren());
}
} }
}, }
}
traverse: function (callback) {
this._traverse(this.root, callback); traverse(callback) {
}, this._traverse(this.root, callback);
}
_recursion: function (node, route, callback) {
var self = this; _recursion(node, route, callback) {
return BI.every(node.getChildren(), function (i, child) { return every(node.getChildren(), (i, child) => {
var next = BI.clone(route); const next = clone(route);
next.push(child.id); next.push(child.id);
var b = callback && callback(child, next); const b = callback && callback(child, next);
if (b === false) { if (b === false) {
return false; return false;
}
if (b === true) {
return true;
}
return self._recursion(child, next, callback);
});
},
recursion: function (callback) {
this._recursion(this.root, [], callback);
},
inOrderTraverse: function (callback) {
this._inOrderTraverse(this.root, callback);
},
// 中序遍历(递归)
_inOrderTraverse: function (node, callback) {
if (node != null) {
this._inOrderTraverse(node.getLeft());
callback && callback(node);
this._inOrderTraverse(node.getRight());
} }
}, if (b === true) {
return true;
// 中序遍历(非递归)
nrInOrderTraverse: function (callback) {
var stack = [];
var node = this.root;
while (node != null || !BI.isEmpty(stack)) {
while (node != null) {
stack.push(node);
node = node.getLeft();
}
node = stack.pop();
callback && callback(node);
node = node.getRight();
} }
}, return this._recursion(child, next, callback);
});
}
recursion(callback) {
this._recursion(this.root, [], callback);
}
inOrderTraverse(callback) {
this._inOrderTraverse(this.root, callback);
}
// 中序遍历(递归)
_inOrderTraverse(node, callback) {
if (node != null) {
this._inOrderTraverse(node.getLeft());
callback && callback(node);
this._inOrderTraverse(node.getRight());
}
}
preOrderTraverse: function (callback) { // 中序遍历(非递归)
this._preOrderTraverse(this.root, callback); nrInOrderTraverse(callback) {
},
// 先序遍历(递归) const stack = [];
_preOrderTraverse: function (node, callback) { let node = this.root;
if (node != null) { while (node != null || !isEmpty(stack)) {
callback && callback(node); while (node != null) {
this._preOrderTraverse(node.getLeft()); stack.push(node);
this._preOrderTraverse(node.getRight()); node = node.getLeft();
} }
}, node = stack.pop();
callback && callback(node);
// 先序遍历(非递归) node = node.getRight();
nrPreOrderTraverse: function (callback) { }
}
var stack = [];
var node = this.root; preOrderTraverse(callback) {
this._preOrderTraverse(this.root, callback);
}
// 先序遍历(递归)
_preOrderTraverse(node, callback) {
if (node != null) {
callback && callback(node);
this._preOrderTraverse(node.getLeft());
this._preOrderTraverse(node.getRight());
}
}
while (node != null || !BI.isEmpty(stack)) { // 先序遍历(非递归)
nrPreOrderTraverse(callback) {
while (node != null) { const stack = [];
callback && callback(node); let node = this.root;
stack.push(node);
node = node.getLeft();
}
node = stack.pop();
node = node.getRight();
}
},
postOrderTraverse: function (callback) { while (node != null || !isEmpty(stack)) {
this._postOrderTraverse(this.root, callback);
},
// 后序遍历(递归) while (node != null) {
_postOrderTraverse: function (node, callback) {
if (node != null) {
this._postOrderTraverse(node.getLeft());
this._postOrderTraverse(node.getRight());
callback && callback(node); callback && callback(node);
stack.push(node);
node = node.getLeft();
} }
}, node = stack.pop();
node = node.getRight();
// 后续遍历(非递归)
nrPostOrderTraverse: function (callback) {
var stack = [];
var node = this.root;
var preNode = null;// 表示最近一次访问的节点
while (node != null || !BI.isEmpty(stack)) {
while (node != null) {
stack.push(node);
node = node.getLeft();
}
node = BI.last(stack);
if (node.getRight() == null || node.getRight() == preNode) {
callback && callback(node);
node = stack.pop();
preNode = node;
node = null;
} else {
node = node.getRight();
}
}
} }
}; }
BI.Node = function (id) { postOrderTraverse(callback) {
if (BI.isObject(id)) { this._postOrderTraverse(this.root, callback);
BI.extend(this, id); }
} else {
this.id = id; // 后序遍历(递归)
_postOrderTraverse(node, callback) {
if (node != null) {
this._postOrderTraverse(node.getLeft());
this._postOrderTraverse(node.getRight());
callback && callback(node);
} }
this.clear.apply(this, arguments); }
};
BI.Node.prototype = {
constructor: BI.Node,
set: function (key, value) {
if (BI.isObject(key)) {
BI.extend(this, key);
return;
}
this[key] = value;
},
get: function (key) {
return this[key];
},
isLeaf: function () {
return BI.isEmpty(this.children);
},
getChildren: function () {
return this.children;
},
getChildrenLength: function () {
return this.children.length;
},
getFirstChild: function () {
return BI.first(this.children);
},
getLastChild: function () {
return BI.last(this.children);
},
setLeft: function (left) { // 后续遍历(非递归)
this.left = left; nrPostOrderTraverse(callback) {
},
getLeft: function () { const stack = [];
return this.left; let node = this.root;
}, let preNode = null;// 表示最近一次访问的节点
setRight: function (right) { while (node != null || !isEmpty(stack)) {
this.right = right;
},
getRight: function () { while (node != null) {
return this.right; stack.push(node);
}, node = node.getLeft();
setParent: function (parent) {
this.parent = parent;
},
getParent: function () {
return this.parent;
},
getChild: function (index) {
return this.children[index];
},
getChildIndex: function (id) {
return BI.findIndex(this.children, function (i, ch) {
return ch.get("id") === id;
});
},
removeChild: function (id) {
this.removeChildByIndex(this.getChildIndex(id));
},
removeChildByIndex: function (index) {
var before = this.getChild(index - 1);
var behind = this.getChild(index + 1);
if (before != null) {
before.setRight(behind || null);
}
if (behind != null) {
behind.setLeft(before || null);
} }
this.children.splice(index, 1);
},
removeAllChilds: function () { node = last(stack);
this.children = [];
},
addChild: function (child, index) { if (node.getRight() == null || node.getRight() === preNode) {
var cur = null; callback && callback(node);
if (BI.isUndefined(index)) { node = stack.pop();
cur = this.children.length - 1; preNode = node;
node = null;
} else { } else {
cur = index - 1; node = node.getRight();
} }
child.setParent(this); }
if (cur >= 0) { }
this.getChild(cur) && this.getChild(cur).setRight(child);
child.setLeft(this.getChild(cur)); static transformToArrayFormat(nodes, pId, childKey) {
if (!nodes) return [];
let r = [];
childKey = childKey || "children";
if (isArray(nodes)) {
for (let i = 0, l = nodes.length; i < l; i++) {
const node = clone(nodes[i]);
node.pId = node.pId == null ? pId : node.pId;
delete node.children;
r.push(node);
if (nodes[i][childKey]) {
r = r.concat(Tree.transformToArrayFormat(nodes[i][childKey], node.id));
}
} }
if (BI.isUndefined(index)) { } else {
this.children.push(child); const newNodes = clone(nodes);
} else { newNodes.pId = newNodes.pId == null ? pId : newNodes.pId;
this.children.splice(index, 0, child); delete newNodes.children;
r.push(newNodes);
if (nodes[childKey]) {
r = r.concat(Tree.transformToArrayFormat(nodes[childKey], newNodes.id));
} }
}, }
return r;
equals: function (obj) { }
return this === obj || this.id === obj.id;
},
clear: function () { static arrayFormat(nodes, pId) {
this.parent = null; if (!nodes) {
this.left = null; return [];
this.right = null;
this.children = [];
} }
}; let r = [];
if (isArray(nodes)) {
BI.extend(BI.Tree, { for (let i = 0, l = nodes.length; i < l; i++) {
transformToArrayFormat: function (nodes, pId, childKey) { const node = nodes[i];
if (!nodes) return []; node.pId = node.pId == null ? pId : node.pId;
var r = []; r.push(node);
childKey = childKey || "children"; if (nodes[i]["children"]) {
if (BI.isArray(nodes)) { r = r.concat(Tree.arrayFormat(nodes[i]["children"], node.id));
for (var i = 0, l = nodes.length; i < l; i++) {
var node = BI.clone(nodes[i]);
node.pId = node.pId == null ? pId : node.pId;
delete node.children;
r.push(node);
if (nodes[i][childKey]) {
r = r.concat(BI.Tree.transformToArrayFormat(nodes[i][childKey], node.id));
}
}
} else {
var newNodes = BI.clone(nodes);
newNodes.pId = newNodes.pId == null ? pId : newNodes.pId;
delete newNodes.children;
r.push(newNodes);
if (nodes[childKey]) {
r = r.concat(BI.Tree.transformToArrayFormat(nodes[childKey], newNodes.id));
} }
} }
return r; } else {
}, const newNodes = nodes;
newNodes.pId = newNodes.pId == null ? pId : newNodes.pId;
arrayFormat: function (nodes, pId) { r.push(newNodes);
if (!nodes) { if (nodes["children"]) {
return []; r = r.concat(Tree.arrayFormat(nodes["children"], newNodes.id));
}
var r = [];
if (BI.isArray(nodes)) {
for (var i = 0, l = nodes.length; i < l; i++) {
var node = nodes[i];
node.pId = node.pId == null ? pId : node.pId;
r.push(node);
if (nodes[i]["children"]) {
r = r.concat(BI.Tree.arrayFormat(nodes[i]["children"], node.id));
}
}
} else {
var newNodes = nodes;
newNodes.pId = newNodes.pId == null ? pId : newNodes.pId;
r.push(newNodes);
if (nodes["children"]) {
r = r.concat(BI.Tree.arrayFormat(nodes["children"], newNodes.id));
}
} }
return r; }
}, return r;
}
transformToTreeFormat: function (sNodes) { static transformToTreeFormat(sNodes) {
var i, l; let i, l;
if (!sNodes) { if (!sNodes) {
return []; return [];
} }
if (BI.isArray(sNodes)) { if (isArray(sNodes)) {
var r = []; const r = [];
var tmpMap = {}; const tmpMap = {};
for (i = 0, l = sNodes.length; i < l; i++) { for (i = 0, l = sNodes.length; i < l; i++) {
if (BI.isNull(sNodes[i].id)) { if (isNull(sNodes[i].id)) {
return sNodes; return sNodes;
}
tmpMap[sNodes[i].id] = BI.clone(sNodes[i]);
} }
for (i = 0, l = sNodes.length; i < l; i++) { tmpMap[sNodes[i].id] = clone(sNodes[i]);
if (tmpMap[sNodes[i].pId] && sNodes[i].id !== sNodes[i].pId) { }
if (!tmpMap[sNodes[i].pId].children) { for (i = 0, l = sNodes.length; i < l; i++) {
tmpMap[sNodes[i].pId].children = []; if (tmpMap[sNodes[i].pId] && sNodes[i].id !== sNodes[i].pId) {
} if (!tmpMap[sNodes[i].pId].children) {
tmpMap[sNodes[i].pId].children.push(tmpMap[sNodes[i].id]); tmpMap[sNodes[i].pId].children = [];
} else {
r.push(tmpMap[sNodes[i].id]);
} }
delete tmpMap[sNodes[i].id].pId; tmpMap[sNodes[i].pId].children.push(tmpMap[sNodes[i].id]);
} else {
r.push(tmpMap[sNodes[i].id]);
} }
return r; delete tmpMap[sNodes[i].id].pId;
} }
return [sNodes]; return r;
}
return [sNodes];
}, }
treeFormat: function (sNodes) { static treeFormat(sNodes) {
var i, l; let i, l;
if (!sNodes) { if (!sNodes) {
return []; return [];
} }
if (BI.isArray(sNodes)) { if (isArray(sNodes)) {
var r = []; const r = [];
var tmpMap = {}; const tmpMap = {};
for (i = 0, l = sNodes.length; i < l; i++) { for (i = 0, l = sNodes.length; i < l; i++) {
if (BI.isNull(sNodes[i].id)) { if (isNull(sNodes[i].id)) {
return sNodes; return sNodes;
}
tmpMap[sNodes[i].id] = sNodes[i];
} }
for (i = 0, l = sNodes.length; i < l; i++) { tmpMap[sNodes[i].id] = sNodes[i];
if (tmpMap[sNodes[i].pId] && sNodes[i].id !== sNodes[i].pId) { }
if (!tmpMap[sNodes[i].pId].children) { for (i = 0, l = sNodes.length; i < l; i++) {
tmpMap[sNodes[i].pId].children = []; if (tmpMap[sNodes[i].pId] && sNodes[i].id !== sNodes[i].pId) {
} if (!tmpMap[sNodes[i].pId].children) {
tmpMap[sNodes[i].pId].children.push(tmpMap[sNodes[i].id]); tmpMap[sNodes[i].pId].children = [];
} else {
r.push(tmpMap[sNodes[i].id]);
} }
tmpMap[sNodes[i].pId].children.push(tmpMap[sNodes[i].id]);
} else {
r.push(tmpMap[sNodes[i].id]);
} }
return r;
} }
return [sNodes]; return r;
}
return [sNodes];
}, }
traversal: function (array, callback, pNode) { static traversal(array, callback, pNode) {
if (BI.isNull(array)) { if (isNull(array)) {
return; return;
}
var self = this;
BI.some(array, function (i, item) {
if (callback(i, item, pNode) === false) {
return true;
}
self.traversal(item.children, callback, item);
});
} }
}); some(array, (i, item) => {
})(); if (callback(i, item, pNode) === false) {
return true;
}
this.traversal(item.children, callback, item);
});
}
}

61
src/core/structure/vector.js

@ -1,27 +1,29 @@
// 向量操作 // 向量操作
BI.Vector = function (x, y) { export class Vector {
this.x = x; constructor(x, y) {
this.y = y; this.x = x;
}; this.y = y;
BI.Vector.prototype = { }
constructor: BI.Vector,
cross: function (v) { cross(v) {
return (this.x * v.y - this.y * v.x); return (this.x * v.y - this.y * v.x);
}, }
length: function (v) {
length(v) {
return (Math.sqrt(this.x * v.x + this.y * v.y)); return (Math.sqrt(this.x * v.x + this.y * v.y));
} }
}; }
BI.Region = function (x, y, w, h) {
this.x = x; export class Region {
this.y = y; constructor(x, y, w, h) {
this.w = w; this.x = x;
this.h = h; this.y = y;
}; this.w = w;
BI.Region.prototype = { this.h = h;
constructor: BI.Region, }
// 判断两个区域是否相交,若相交,则要么顶点互相包含,要么矩形边界(或对角线)相交 // 判断两个区域是否相交,若相交,则要么顶点互相包含,要么矩形边界(或对角线)相交
isIntersects: function (obj) { isIntersects(obj) {
if (this.isPointInside(obj.x, obj.y) || if (this.isPointInside(obj.x, obj.y) ||
this.isPointInside(obj.x + obj.w, obj.y) || this.isPointInside(obj.x + obj.w, obj.y) ||
this.isPointInside(obj.x, obj.y + obj.h) || this.isPointInside(obj.x, obj.y + obj.h) ||
@ -34,17 +36,18 @@ BI.Region.prototype = {
return true; return true;
} else if (obj.x != null && obj.y != null)// 判断矩形对角线相交 |v1 X v2||v1 X v3| < 0 } else if (obj.x != null && obj.y != null)// 判断矩形对角线相交 |v1 X v2||v1 X v3| < 0
{ {
var vector1 = new BI.Vector(this.w, this.h);// 矩形对角线向量 const vector1 = new Vector(this.w, this.h);// 矩形对角线向量
var vector2 = new BI.Vector(obj.x - this.x, obj.y - this.y); const vector2 = new Vector(obj.x - this.x, obj.y - this.y);
var vector3 = new BI.Vector(vector2.x + obj.w, vector2.y + obj.h); const vector3 = new Vector(vector2.x + obj.w, vector2.y + obj.h);
if ((vector1.cross(vector2) * vector1.cross(vector3)) < 0) { if ((vector1.cross(vector2) * vector1.cross(vector3)) < 0) {
return true; return true;
} }
} }
return false; return false;
}, }
// 判断一个点是否在这个区域内部 // 判断一个点是否在这个区域内部
isPointInside: function (x, y) { isPointInside(x, y) {
if (this.x == null || this.y == null) { if (this.x == null || this.y == null) {
return false; return false;
} }
@ -52,12 +55,14 @@ BI.Region.prototype = {
return true; return true;
} }
return false; return false;
}, }
// 返回区域的重心,因为是矩形所以返回中点 // 返回区域的重心,因为是矩形所以返回中点
getPosition: function () { getPosition() {
var pos = []; const pos = [];
pos.push(this.x + this.w / 2); pos.push(this.x + this.w / 2);
pos.push(this.y + this.h / 2); pos.push(this.y + this.h / 2);
return pos; return pos;
} }
}; }

Loading…
Cancel
Save