UNPKG

leafer-editor

Version:

**leafer-editor** 在 [leafer-ui](https://github.com/leaferjs/leafer-ui) 的基础上,集成了 图形编辑器、视图控制 、滚动条、箭头、HTML 插件,适用于在线图形编辑的场景。

1,662 lines (1,585 loc) 613 kB
const Platform = { toURL(text, fileType) { let url = encodeURIComponent(text); if (fileType === "text") url = "data:text/plain;charset=utf-8," + url; else if (fileType === "svg") url = "data:image/svg+xml," + url; return url; }, image: { hitCanvasSize: 100, maxCacheSize: 2560 * 1600, maxPatternSize: 4096 * 2160, crossOrigin: "anonymous", getRealURL(url) { const {prefix: prefix, suffix: suffix} = Platform.image; if (suffix && !url.startsWith("data:") && !url.startsWith("blob:")) url += (url.includes("?") ? "&" : "?") + suffix; if (prefix && url[0] === "/") url = prefix + url; return url; } } }; const IncrementId = { RUNTIME: "runtime", LEAF: "leaf", TASK: "task", CNAVAS: "canvas", IMAGE: "image", types: {}, create(typeName) { const {types: types} = I$2; if (types[typeName]) { return types[typeName]++; } else { types[typeName] = 1; return 0; } } }; const I$2 = IncrementId; var Answer; (function(Answer) { Answer[Answer["No"] = 0] = "No"; Answer[Answer["Yes"] = 1] = "Yes"; Answer[Answer["NoAndSkip"] = 2] = "NoAndSkip"; Answer[Answer["YesAndSkip"] = 3] = "YesAndSkip"; })(Answer || (Answer = {})); const emptyData = {}; function isUndefined(value) { return value === undefined; } function isNull(value) { return value == null; } function isString(value) { return typeof value === "string"; } const {isFinite: isFinite} = Number; function isNumber(value) { return typeof value === "number"; } const numberReg = /^-?\d+(?:\.\d+)?$/; function tryToNumber(value) { return typeof value === "string" && numberReg.test(value) ? +value : value; } const {isArray: isArray} = Array; function isObject(value) { return value && typeof value === "object"; } function isData(value) { return isObject(value) && !isArray(value); } function isEmptyData(value) { return JSON.stringify(value) === "{}"; } const DataHelper = { default(t, defaultData) { assign(defaultData, t); assign(t, defaultData); return t; }, assign(t, merge, exclude) { let value; Object.keys(merge).forEach(key => { var _a, _b; value = merge[key]; if ((value === null || value === void 0 ? void 0 : value.constructor) === Object && ((_a = t[key]) === null || _a === void 0 ? void 0 : _a.constructor) === Object) return assign(t[key], merge[key], exclude && exclude[key]); if (exclude && key in exclude) { if (((_b = exclude[key]) === null || _b === void 0 ? void 0 : _b.constructor) === Object) assign(t[key] = {}, merge[key], exclude[key]); return; } t[key] = merge[key]; }); }, copyAttrs(t, from, include) { include.forEach(key => { if (!isUndefined(from[key])) t[key] = from[key]; }); return t; }, clone(data) { return JSON.parse(JSON.stringify(data)); }, toMap(list) { const map = {}; for (let i = 0, len = list.length; i < len; i++) map[list[i]] = true; return map; }, stintSet(data, attrName, value) { value || (value = undefined); data[attrName] !== value && (data[attrName] = value); } }; const {assign: assign} = DataHelper; class LeafData { get __useNaturalRatio() { return true; } get __isLinePath() { const {path: path} = this; return path && path.length === 6 && path[0] === 1; } get __usePathBox() { return this.__pathInputed; } get __blendMode() { if (this.eraser && this.eraser !== "path") return "destination-out"; const {blendMode: blendMode} = this; return blendMode === "pass-through" ? null : blendMode; } constructor(leaf) { this.__leaf = leaf; } __get(name) { if (this.__input) { const value = this.__input[name]; if (!isUndefined(value)) return value; } return this[name]; } __getData() { const data = { tag: this.__leaf.tag }, {__input: __input} = this; let inputValue; for (let key in this) { if (key[0] !== "_") { inputValue = __input ? __input[key] : undefined; data[key] = isUndefined(inputValue) ? this[key] : inputValue; } } return data; } __setInput(name, value) { this.__input || (this.__input = {}); this.__input[name] = value; } __getInput(name) { if (this.__input) { const value = this.__input[name]; if (!isUndefined(value)) return value; } if (name === "path" && !this.__pathInputed) return; return this["_" + name]; } __removeInput(name) { if (this.__input && !isUndefined(this.__input[name])) this.__input[name] = undefined; } __getInputData(names, options) { const data = {}; if (names) { if (isArray(names)) { for (let name of names) data[name] = this.__getInput(name); } else { for (let name in names) data[name] = this.__getInput(name); } } else { let value, inputValue, {__input: __input} = this; data.tag = this.__leaf.tag; for (let key in this) { if (key[0] !== "_") { value = this["_" + key]; if (!isUndefined(value)) { if (key === "path" && !this.__pathInputed) continue; inputValue = __input ? __input[key] : undefined; data[key] = isUndefined(inputValue) ? value : inputValue; } } } } if (options) { if (options.matrix) { const {a: a, b: b, c: c, d: d, e: e, f: f} = this.__leaf.__localMatrix; data.matrix = { a: a, b: b, c: c, d: d, e: e, f: f }; } } return data; } __setMiddle(name, value) { this.__middle || (this.__middle = {}); this.__middle[name] = value; } __getMiddle(name) { return this.__middle && this.__middle[name]; } __checkSingle() { const t = this; if (t.blendMode === "pass-through") { const leaf = this.__leaf; if (t.opacity < 1 && (leaf.isBranch || t.__hasMultiPaint) || leaf.__hasEraser || t.eraser || t.filter) { t.__single = true; } else if (t.__single) { t.__single = false; } } else { t.__single = true; } } __removeNaturalSize() { this.__naturalWidth = this.__naturalHeight = undefined; } destroy() { this.__input = this.__middle = null; } } let tempA, tempB, tempTo; const {max: max$5} = Math, tempFour = [ 0, 0, 0, 0 ]; const FourNumberHelper = { zero: [ ...tempFour ], tempFour: tempFour, set(to, top, right, bottom, left) { if (right === undefined) right = bottom = left = top; to[0] = top; to[1] = right; to[2] = bottom; to[3] = left; return to; }, setTemp(top, right, bottom, left) { return set$1(tempFour, top, right, bottom, left); }, toTempAB(a, b, change) { tempTo = change ? isNumber(a) ? b : a : []; if (isNumber(a)) tempA = setTemp(a), tempB = b; else if (isNumber(b)) tempA = a, tempB = setTemp(b); else tempA = a, tempB = b; if (tempA.length !== 4) tempA = get$5(tempA); if (tempB.length !== 4) tempB = get$5(tempB); }, get(num, maxValue) { let data; if (!isNumber(num)) { switch (num.length) { case 4: data = isUndefined(maxValue) ? num : [ ...num ]; break; case 2: data = [ num[0], num[1], num[0], num[1] ]; break; case 3: data = [ num[0], num[1], num[2], num[1] ]; break; case 1: num = num[0]; break; default: num = 0; } } if (!data) data = [ num, num, num, num ]; if (!isUndefined(maxValue)) for (let i = 0; i < 4; i++) if (data[i] > maxValue) data[i] = maxValue; return data; }, max(t, other, change) { if (isNumber(t) && isNumber(other)) return max$5(t, other); toTempAB(t, other, change); return set$1(tempTo, max$5(tempA[0], tempB[0]), max$5(tempA[1], tempB[1]), max$5(tempA[2], tempB[2]), max$5(tempA[3], tempB[3])); }, add(t, other, change) { if (isNumber(t) && isNumber(other)) return t + other; toTempAB(t, other, change); return set$1(tempTo, tempA[0] + tempB[0], tempA[1] + tempB[1], tempA[2] + tempB[2], tempA[3] + tempB[3]); }, swapAndScale(t, scaleX, scaleY, change) { if (isNumber(t)) return scaleX === scaleY ? t * scaleX : [ t * scaleY, t * scaleX ]; const to = change ? t : []; const [top, right, bottom, left] = t.length === 4 ? t : get$5(t); return set$1(to, bottom * scaleY, left * scaleX, top * scaleY, right * scaleX); } }; const {set: set$1, get: get$5, setTemp: setTemp, toTempAB: toTempAB} = FourNumberHelper; const {round: round$3, pow: pow$1, PI: PI$3} = Math; const MathHelper = { within(value, min, max) { if (isObject(min)) max = min.max, min = min.min; if (!isUndefined(min) && value < min) value = min; if (!isUndefined(max) && value > max) value = max; return value; }, fourNumber: FourNumberHelper.get, formatRotation(rotation, unsign) { rotation %= 360; if (unsign) { if (rotation < 0) rotation += 360; } else { if (rotation > 180) rotation -= 360; if (rotation < -180) rotation += 360; } return MathHelper.float(rotation); }, getGapRotation(addRotation, gap, oldRotation = 0) { let rotation = addRotation + oldRotation; if (gap > 1) { const r = Math.abs(rotation % gap); if (r < 1 || r > gap - 1) rotation = Math.round(rotation / gap) * gap; } return rotation - oldRotation; }, float(num, maxLength) { const a = !isUndefined(maxLength) ? pow$1(10, maxLength) : 1e12; num = round$3(num * a) / a; return num === -0 ? 0 : num; }, sign(num) { return num < 0 ? -1 : 1; }, getScaleData(scale, size, originSize, scaleData) { if (!scaleData) scaleData = {}; if (size) { const scaleX = (isNumber(size) ? size : size.width || 0) / originSize.width, scaleY = (isNumber(size) ? size : size.height || 0) / originSize.height; scaleData.scaleX = scaleX || scaleY || 1; scaleData.scaleY = scaleY || scaleX || 1; } else if (scale) MathHelper.assignScale(scaleData, scale); return scaleData; }, assignScale(scaleData, scale) { if (isNumber(scale)) { scaleData.scaleX = scaleData.scaleY = scale; } else { scaleData.scaleX = scale.x; scaleData.scaleY = scale.y; } }, randInt: randInt, randColor(opacity) { return `rgba(${randInt(255)},${randInt(255)},${randInt(255)},${opacity || 1})`; } }; function randInt(num) { return Math.round(Math.random() * num); } const OneRadian = PI$3 / 180; const PI2 = PI$3 * 2; const PI_2 = PI$3 / 2; function getPointData() { return { x: 0, y: 0 }; } function getBoundsData() { return { x: 0, y: 0, width: 0, height: 0 }; } function getMatrixData() { return { a: 1, b: 0, c: 0, d: 1, e: 0, f: 0 }; } const {sin: sin$5, cos: cos$5, acos: acos, sqrt: sqrt$3} = Math; const {float: float$2} = MathHelper; const tempPoint$3 = {}; function getWorld() { return Object.assign(Object.assign(Object.assign({}, getMatrixData()), getBoundsData()), { scaleX: 1, scaleY: 1, rotation: 0, skewX: 0, skewY: 0 }); } const MatrixHelper = { defaultMatrix: getMatrixData(), defaultWorld: getWorld(), tempMatrix: {}, set(t, a = 1, b = 0, c = 0, d = 1, e = 0, f = 0) { t.a = a; t.b = b; t.c = c; t.d = d; t.e = e; t.f = f; }, get: getMatrixData, getWorld: getWorld, copy(t, matrix) { t.a = matrix.a; t.b = matrix.b; t.c = matrix.c; t.d = matrix.d; t.e = matrix.e; t.f = matrix.f; }, translate(t, x, y) { t.e += x; t.f += y; }, translateInner(t, x, y, hasOrigin) { t.e += t.a * x + t.c * y; t.f += t.b * x + t.d * y; if (hasOrigin) t.e -= x, t.f -= y; }, scale(t, scaleX, scaleY = scaleX) { t.a *= scaleX; t.b *= scaleX; t.c *= scaleY; t.d *= scaleY; }, pixelScale(t, pixelRatio, to) { to || (to = t); to.a = t.a * pixelRatio; to.b = t.b * pixelRatio; to.c = t.c * pixelRatio; to.d = t.d * pixelRatio; to.e = t.e * pixelRatio; to.f = t.f * pixelRatio; }, scaleOfOuter(t, origin, scaleX, scaleY) { M$a.toInnerPoint(t, origin, tempPoint$3); M$a.scaleOfInner(t, tempPoint$3, scaleX, scaleY); }, scaleOfInner(t, origin, scaleX, scaleY = scaleX) { M$a.translateInner(t, origin.x, origin.y); M$a.scale(t, scaleX, scaleY); M$a.translateInner(t, -origin.x, -origin.y); }, rotate(t, rotation) { const {a: a, b: b, c: c, d: d} = t; rotation *= OneRadian; const cosR = cos$5(rotation); const sinR = sin$5(rotation); t.a = a * cosR - b * sinR; t.b = a * sinR + b * cosR; t.c = c * cosR - d * sinR; t.d = c * sinR + d * cosR; }, rotateOfOuter(t, origin, rotation) { M$a.toInnerPoint(t, origin, tempPoint$3); M$a.rotateOfInner(t, tempPoint$3, rotation); }, rotateOfInner(t, origin, rotation) { M$a.translateInner(t, origin.x, origin.y); M$a.rotate(t, rotation); M$a.translateInner(t, -origin.x, -origin.y); }, skew(t, skewX, skewY) { const {a: a, b: b, c: c, d: d} = t; if (skewY) { skewY *= OneRadian; t.a = a + c * skewY; t.b = b + d * skewY; } if (skewX) { skewX *= OneRadian; t.c = c + a * skewX; t.d = d + b * skewX; } }, skewOfOuter(t, origin, skewX, skewY) { M$a.toInnerPoint(t, origin, tempPoint$3); M$a.skewOfInner(t, tempPoint$3, skewX, skewY); }, skewOfInner(t, origin, skewX, skewY = 0) { M$a.translateInner(t, origin.x, origin.y); M$a.skew(t, skewX, skewY); M$a.translateInner(t, -origin.x, -origin.y); }, multiply(t, child) { const {a: a, b: b, c: c, d: d, e: e, f: f} = t; t.a = child.a * a + child.b * c; t.b = child.a * b + child.b * d; t.c = child.c * a + child.d * c; t.d = child.c * b + child.d * d; t.e = child.e * a + child.f * c + e; t.f = child.e * b + child.f * d + f; }, multiplyParent(t, parent, to, abcdChanged, childScaleData) { const {e: e, f: f} = t; to || (to = t); if (isUndefined(abcdChanged)) abcdChanged = t.a !== 1 || t.b || t.c || t.d !== 1; if (abcdChanged) { const {a: a, b: b, c: c, d: d} = t; to.a = a * parent.a + b * parent.c; to.b = a * parent.b + b * parent.d; to.c = c * parent.a + d * parent.c; to.d = c * parent.b + d * parent.d; if (childScaleData) { to.scaleX = parent.scaleX * childScaleData.scaleX; to.scaleY = parent.scaleY * childScaleData.scaleY; } } else { to.a = parent.a; to.b = parent.b; to.c = parent.c; to.d = parent.d; if (childScaleData) { to.scaleX = parent.scaleX; to.scaleY = parent.scaleY; } } to.e = e * parent.a + f * parent.c + parent.e; to.f = e * parent.b + f * parent.d + parent.f; }, divide(t, child) { M$a.multiply(t, M$a.tempInvert(child)); }, divideParent(t, parent) { M$a.multiplyParent(t, M$a.tempInvert(parent)); }, tempInvert(t) { const {tempMatrix: tempMatrix} = M$a; M$a.copy(tempMatrix, t); M$a.invert(tempMatrix); return tempMatrix; }, invert(t) { const {a: a, b: b, c: c, d: d, e: e, f: f} = t; if (!b && !c) { if (a === 1 && d === 1) { t.e = -e; t.f = -f; } else { const s = 1 / (a * d); t.a = d * s; t.d = a * s; t.e = -e * d * s; t.f = -f * a * s; } } else { const s = 1 / (a * d - b * c); t.a = d * s; t.b = -b * s; t.c = -c * s; t.d = a * s; t.e = -(e * d - f * c) * s; t.f = -(f * a - e * b) * s; } }, toOuterPoint(t, inner, to, distance) { const {x: x, y: y} = inner; to || (to = inner); to.x = x * t.a + y * t.c; to.y = x * t.b + y * t.d; if (!distance) { to.x += t.e; to.y += t.f; } }, toInnerPoint(t, outer, to, distance) { const {a: a, b: b, c: c, d: d} = t; const s = 1 / (a * d - b * c); const {x: x, y: y} = outer; to || (to = outer); to.x = (x * d - y * c) * s; to.y = (y * a - x * b) * s; if (!distance) { const {e: e, f: f} = t; to.x -= (e * d - f * c) * s; to.y -= (f * a - e * b) * s; } }, setLayout(t, layout, origin, around, bcChanged) { const {x: x, y: y, scaleX: scaleX, scaleY: scaleY} = layout; if (isUndefined(bcChanged)) bcChanged = layout.rotation || layout.skewX || layout.skewY; if (bcChanged) { const {rotation: rotation, skewX: skewX, skewY: skewY} = layout; const r = rotation * OneRadian; const cosR = cos$5(r); const sinR = sin$5(r); if (skewX || skewY) { const sx = skewX * OneRadian; const sy = skewY * OneRadian; t.a = (cosR + sy * -sinR) * scaleX; t.b = (sinR + sy * cosR) * scaleX; t.c = (-sinR + sx * cosR) * scaleY; t.d = (cosR + sx * sinR) * scaleY; } else { t.a = cosR * scaleX; t.b = sinR * scaleX; t.c = -sinR * scaleY; t.d = cosR * scaleY; } } else { t.a = scaleX; t.b = 0; t.c = 0; t.d = scaleY; } t.e = x; t.f = y; if (origin = origin || around) M$a.translateInner(t, -origin.x, -origin.y, !around); }, getLayout(t, origin, around, firstSkewY) { const {a: a, b: b, c: c, d: d, e: e, f: f} = t; let x = e, y = f, scaleX, scaleY, rotation, skewX, skewY; if (b || c) { const s = a * d - b * c; if (c && !firstSkewY) { scaleX = sqrt$3(a * a + b * b); scaleY = s / scaleX; const cosR = a / scaleX; rotation = b > 0 ? acos(cosR) : -acos(cosR); } else { scaleY = sqrt$3(c * c + d * d); scaleX = s / scaleY; const cosR = c / scaleY; rotation = PI_2 - (d > 0 ? acos(-cosR) : -acos(cosR)); } const cosR = float$2(cos$5(rotation)); const sinR = sin$5(rotation); scaleX = float$2(scaleX), scaleY = float$2(scaleY); skewX = cosR ? float$2((c / scaleY + sinR) / cosR / OneRadian, 9) : 0; skewY = cosR ? float$2((b / scaleX - sinR) / cosR / OneRadian, 9) : 0; rotation = float$2(rotation / OneRadian); } else { scaleX = a; scaleY = d; rotation = skewX = skewY = 0; } if (origin = around || origin) { x += origin.x * a + origin.y * c; y += origin.x * b + origin.y * d; if (!around) x -= origin.x, y -= origin.y; } return { x: x, y: y, scaleX: scaleX, scaleY: scaleY, rotation: rotation, skewX: skewX, skewY: skewY }; }, withScale(t, scaleX, scaleY = scaleX) { const world = t; if (!scaleX || !scaleY) { const {a: a, b: b, c: c, d: d} = t; if (b || c) { scaleX = sqrt$3(a * a + b * b); scaleY = (a * d - b * c) / scaleX; } else { scaleX = a; scaleY = d; } } world.scaleX = scaleX; world.scaleY = scaleY; return world; }, reset(t) { M$a.set(t); } }; const M$a = MatrixHelper; const {toInnerPoint: toInnerPoint$2, toOuterPoint: toOuterPoint$3} = MatrixHelper; const {sin: sin$4, cos: cos$4, abs: abs$6, sqrt: sqrt$2, atan2: atan2$2, min: min$1, round: round$2} = Math; const PointHelper = { defaultPoint: getPointData(), tempPoint: {}, tempRadiusPoint: {}, set(t, x = 0, y = 0) { t.x = x; t.y = y; }, setRadius(t, x, y) { t.radiusX = x; t.radiusY = isUndefined(y) ? x : y; }, copy(t, point) { t.x = point.x; t.y = point.y; }, copyFrom(t, x, y) { t.x = x; t.y = y; }, round(t, halfPixel) { t.x = halfPixel ? round$2(t.x - .5) + .5 : round$2(t.x); t.y = halfPixel ? round$2(t.y - .5) + .5 : round$2(t.y); }, move(t, x, y) { if (isObject(x)) t.x += x.x, t.y += x.y; else t.x += x, t.y += y; }, scale(t, scaleX, scaleY = scaleX) { if (t.x) t.x *= scaleX; if (t.y) t.y *= scaleY; }, scaleOf(t, origin, scaleX, scaleY = scaleX) { t.x += (t.x - origin.x) * (scaleX - 1); t.y += (t.y - origin.y) * (scaleY - 1); }, rotate(t, rotation, origin) { if (!origin) origin = P$7.defaultPoint; rotation *= OneRadian; const cosR = cos$4(rotation); const sinR = sin$4(rotation); const rx = t.x - origin.x; const ry = t.y - origin.y; t.x = origin.x + rx * cosR - ry * sinR; t.y = origin.y + rx * sinR + ry * cosR; }, tempToInnerOf(t, matrix) { const {tempPoint: temp} = P$7; copy$d(temp, t); toInnerPoint$2(matrix, temp, temp); return temp; }, tempToOuterOf(t, matrix) { const {tempPoint: temp} = P$7; copy$d(temp, t); toOuterPoint$3(matrix, temp, temp); return temp; }, tempToInnerRadiusPointOf(t, matrix) { const {tempRadiusPoint: temp} = P$7; copy$d(temp, t); P$7.toInnerRadiusPointOf(t, matrix, temp); return temp; }, toInnerRadiusPointOf(t, matrix, to) { to || (to = t); toInnerPoint$2(matrix, t, to); to.radiusX = Math.abs(t.radiusX / matrix.scaleX); to.radiusY = Math.abs(t.radiusY / matrix.scaleY); }, toInnerOf(t, matrix, to) { toInnerPoint$2(matrix, t, to); }, toOuterOf(t, matrix, to) { toOuterPoint$3(matrix, t, to); }, getCenter(t, to) { return { x: t.x + (to.x - t.x) / 2, y: t.y + (to.y - t.y) / 2 }; }, getCenterX(x1, x2) { return x1 + (x2 - x1) / 2; }, getCenterY(y1, y2) { return y1 + (y2 - y1) / 2; }, getDistance(t, point) { return getDistanceFrom(t.x, t.y, point.x, point.y); }, getDistanceFrom(x1, y1, x2, y2) { const x = abs$6(x2 - x1); const y = abs$6(y2 - y1); return sqrt$2(x * x + y * y); }, getMinDistanceFrom(x1, y1, x2, y2, x3, y3) { return min$1(getDistanceFrom(x1, y1, x2, y2), getDistanceFrom(x2, y2, x3, y3)); }, getAngle(t, to) { return getAtan2(t, to) / OneRadian; }, getRotation(t, origin, to, toOrigin) { if (!toOrigin) toOrigin = origin; return P$7.getRadianFrom(t.x, t.y, origin.x, origin.y, to.x, to.y, toOrigin.x, toOrigin.y) / OneRadian; }, getRadianFrom(fromX, fromY, originX, originY, toX, toY, toOriginX, toOriginY) { if (isUndefined(toOriginX)) toOriginX = originX, toOriginY = originY; const a = fromX - originX; const b = fromY - originY; const c = toX - toOriginX; const d = toY - toOriginY; return Math.atan2(a * d - b * c, a * c + b * d); }, getAtan2(t, to) { return atan2$2(to.y - t.y, to.x - t.x); }, getDistancePoint(t, to, distance, changeTo) { const r = getAtan2(t, to); to = changeTo ? to : {}; to.x = t.x + cos$4(r) * distance; to.y = t.y + sin$4(r) * distance; return to; }, toNumberPoints(originPoints) { let points = originPoints; if (isObject(originPoints[0])) points = [], originPoints.forEach(p => points.push(p.x, p.y)); return points; }, reset(t) { P$7.reset(t); } }; const P$7 = PointHelper; const {getDistanceFrom: getDistanceFrom, copy: copy$d, getAtan2: getAtan2} = P$7; class Point { constructor(x, y) { this.set(x, y); } set(x, y) { isObject(x) ? PointHelper.copy(this, x) : PointHelper.set(this, x, y); return this; } get() { const {x: x, y: y} = this; return { x: x, y: y }; } clone() { return new Point(this); } move(x, y) { PointHelper.move(this, x, y); return this; } scale(scaleX, scaleY) { PointHelper.scale(this, scaleX, scaleY); return this; } scaleOf(origin, scaleX, scaleY) { PointHelper.scaleOf(this, origin, scaleX, scaleY); return this; } rotate(rotation, origin) { PointHelper.rotate(this, rotation, origin); return this; } rotateOf(origin, rotation) { PointHelper.rotate(this, rotation, origin); return this; } getRotation(origin, to, toOrigin) { return PointHelper.getRotation(this, origin, to, toOrigin); } toInnerOf(matrix, to) { PointHelper.toInnerOf(this, matrix, to); return this; } toOuterOf(matrix, to) { PointHelper.toOuterOf(this, matrix, to); return this; } getCenter(to) { return new Point(PointHelper.getCenter(this, to)); } getDistance(to) { return PointHelper.getDistance(this, to); } getDistancePoint(to, distance, changeTo) { return new Point(PointHelper.getDistancePoint(this, to, distance, changeTo)); } getAngle(to) { return PointHelper.getAngle(this, to); } getAtan2(to) { return PointHelper.getAtan2(this, to); } reset() { PointHelper.reset(this); return this; } } const tempPoint$2 = new Point; class Matrix { constructor(a, b, c, d, e, f) { this.set(a, b, c, d, e, f); } set(a, b, c, d, e, f) { isObject(a) ? MatrixHelper.copy(this, a) : MatrixHelper.set(this, a, b, c, d, e, f); return this; } setWith(dataWithScale) { MatrixHelper.copy(this, dataWithScale); this.scaleX = dataWithScale.scaleX; this.scaleY = dataWithScale.scaleY; return this; } get() { const {a: a, b: b, c: c, d: d, e: e, f: f} = this; return { a: a, b: b, c: c, d: d, e: e, f: f }; } clone() { return new Matrix(this); } translate(x, y) { MatrixHelper.translate(this, x, y); return this; } translateInner(x, y) { MatrixHelper.translateInner(this, x, y); return this; } scale(x, y) { MatrixHelper.scale(this, x, y); return this; } scaleWith(x, y) { MatrixHelper.scale(this, x, y); this.scaleX *= x; this.scaleY *= y || x; return this; } pixelScale(pixelRatio) { MatrixHelper.pixelScale(this, pixelRatio); return this; } scaleOfOuter(origin, x, y) { MatrixHelper.scaleOfOuter(this, origin, x, y); return this; } scaleOfInner(origin, x, y) { MatrixHelper.scaleOfInner(this, origin, x, y); return this; } rotate(angle) { MatrixHelper.rotate(this, angle); return this; } rotateOfOuter(origin, angle) { MatrixHelper.rotateOfOuter(this, origin, angle); return this; } rotateOfInner(origin, angle) { MatrixHelper.rotateOfInner(this, origin, angle); return this; } skew(x, y) { MatrixHelper.skew(this, x, y); return this; } skewOfOuter(origin, x, y) { MatrixHelper.skewOfOuter(this, origin, x, y); return this; } skewOfInner(origin, x, y) { MatrixHelper.skewOfInner(this, origin, x, y); return this; } multiply(child) { MatrixHelper.multiply(this, child); return this; } multiplyParent(parent) { MatrixHelper.multiplyParent(this, parent); return this; } divide(child) { MatrixHelper.divide(this, child); return this; } divideParent(parent) { MatrixHelper.divideParent(this, parent); return this; } invert() { MatrixHelper.invert(this); return this; } invertWith() { MatrixHelper.invert(this); this.scaleX = 1 / this.scaleX; this.scaleY = 1 / this.scaleY; return this; } toOuterPoint(inner, to, distance) { MatrixHelper.toOuterPoint(this, inner, to, distance); } toInnerPoint(outer, to, distance) { MatrixHelper.toInnerPoint(this, outer, to, distance); } setLayout(data, origin, around) { MatrixHelper.setLayout(this, data, origin, around); return this; } getLayout(origin, around, firstSkewY) { return MatrixHelper.getLayout(this, origin, around, firstSkewY); } withScale(scaleX, scaleY) { return MatrixHelper.withScale(this, scaleX, scaleY); } reset() { MatrixHelper.reset(this); } } const tempMatrix$2 = new Matrix; const TwoPointBoundsHelper = { tempPointBounds: {}, setPoint(t, minX, minY) { t.minX = t.maxX = minX; t.minY = t.maxY = minY; }, addPoint(t, x, y) { t.minX = x < t.minX ? x : t.minX; t.minY = y < t.minY ? y : t.minY; t.maxX = x > t.maxX ? x : t.maxX; t.maxY = y > t.maxY ? y : t.maxY; }, addBounds(t, x, y, width, height) { addPoint$4(t, x, y); addPoint$4(t, x + width, y + height); }, copy(t, pb) { t.minX = pb.minX; t.minY = pb.minY; t.maxX = pb.maxX; t.maxY = pb.maxY; }, addPointBounds(t, pb) { t.minX = pb.minX < t.minX ? pb.minX : t.minX; t.minY = pb.minY < t.minY ? pb.minY : t.minY; t.maxX = pb.maxX > t.maxX ? pb.maxX : t.maxX; t.maxY = pb.maxY > t.maxY ? pb.maxY : t.maxY; }, toBounds(t, setBounds) { setBounds.x = t.minX; setBounds.y = t.minY; setBounds.width = t.maxX - t.minX; setBounds.height = t.maxY - t.minY; } }; const {addPoint: addPoint$4} = TwoPointBoundsHelper; var Direction4; (function(Direction4) { Direction4[Direction4["top"] = 0] = "top"; Direction4[Direction4["right"] = 1] = "right"; Direction4[Direction4["bottom"] = 2] = "bottom"; Direction4[Direction4["left"] = 3] = "left"; })(Direction4 || (Direction4 = {})); var Direction9; (function(Direction9) { Direction9[Direction9["topLeft"] = 0] = "topLeft"; Direction9[Direction9["top"] = 1] = "top"; Direction9[Direction9["topRight"] = 2] = "topRight"; Direction9[Direction9["right"] = 3] = "right"; Direction9[Direction9["bottomRight"] = 4] = "bottomRight"; Direction9[Direction9["bottom"] = 5] = "bottom"; Direction9[Direction9["bottomLeft"] = 6] = "bottomLeft"; Direction9[Direction9["left"] = 7] = "left"; Direction9[Direction9["center"] = 8] = "center"; Direction9[Direction9["top-left"] = 0] = "top-left"; Direction9[Direction9["top-right"] = 2] = "top-right"; Direction9[Direction9["bottom-right"] = 4] = "bottom-right"; Direction9[Direction9["bottom-left"] = 6] = "bottom-left"; })(Direction9 || (Direction9 = {})); const directionData = [ { x: 0, y: 0 }, { x: .5, y: 0 }, { x: 1, y: 0 }, { x: 1, y: .5 }, { x: 1, y: 1 }, { x: .5, y: 1 }, { x: 0, y: 1 }, { x: 0, y: .5 }, { x: .5, y: .5 } ]; directionData.forEach(item => item.type = "percent"); const AroundHelper = { directionData: directionData, tempPoint: {}, get: get$4, toPoint(around, box, to, onlyBoxSize, content, onlyContentSize) { const point = get$4(around); to.x = point.x; to.y = point.y; if (point.type === "percent") { to.x *= box.width; to.y *= box.height; if (content) { if (!onlyContentSize) to.x -= content.x, to.y -= content.y; if (point.x) to.x -= point.x === 1 ? content.width : point.x === .5 ? point.x * content.width : 0; if (point.y) to.y -= point.y === 1 ? content.height : point.y === .5 ? point.y * content.height : 0; } } if (!onlyBoxSize) to.x += box.x, to.y += box.y; }, getPoint(around, box, to) { if (!to) to = {}; AroundHelper.toPoint(around, box, to, true); return to; } }; function get$4(around) { return isString(around) ? directionData[Direction9[around]] : around; } const {toPoint: toPoint$6} = AroundHelper; const AlignHelper = { toPoint(align, content, box, to, onlyBoxSize, onlyContentSize) { toPoint$6(align, box, to, onlyBoxSize, content, onlyContentSize); } }; const {tempPointBounds: tempPointBounds$1, setPoint: setPoint$5, addPoint: addPoint$3, toBounds: toBounds$3} = TwoPointBoundsHelper; const {toOuterPoint: toOuterPoint$2} = MatrixHelper; const {float: float$1, fourNumber: fourNumber} = MathHelper; const {floor: floor$2, ceil: ceil$2} = Math; let right$4, bottom$3, boundsRight, boundsBottom; const point$1 = {}; const toPoint$5 = {}; const tempBounds$3 = {}; const BoundsHelper = { tempBounds: tempBounds$3, set(t, x = 0, y = 0, width = 0, height = 0) { t.x = x; t.y = y; t.width = width; t.height = height; }, copy(t, bounds) { t.x = bounds.x; t.y = bounds.y; t.width = bounds.width; t.height = bounds.height; }, copyAndSpread(t, bounds, spread, isShrink, side) { const {x: x, y: y, width: width, height: height} = bounds; if (isArray(spread)) { const four = fourNumber(spread); isShrink ? B.set(t, x + four[3], y + four[0], width - four[1] - four[3], height - four[2] - four[0]) : B.set(t, x - four[3], y - four[0], width + four[1] + four[3], height + four[2] + four[0]); } else { if (isShrink) spread = -spread; B.set(t, x - spread, y - spread, width + spread * 2, height + spread * 2); } if (side) { if (side === "width") t.y = y, t.height = height; else t.x = x, t.width = width; } }, minX(t) { return t.width > 0 ? t.x : t.x + t.width; }, minY(t) { return t.height > 0 ? t.y : t.y + t.height; }, maxX(t) { return t.width > 0 ? t.x + t.width : t.x; }, maxY(t) { return t.height > 0 ? t.y + t.height : t.y; }, move(t, x, y) { t.x += x; t.y += y; }, scroll(t, data) { t.x += data.scrollX; t.y += data.scrollY; }, getByMove(t, x, y) { t = Object.assign({}, t); B.move(t, x, y); return t; }, toOffsetOutBounds(t, to, offsetBounds) { if (!to) to = t; else copy$c(to, t); if (!offsetBounds) offsetBounds = t; to.offsetX = B.maxX(offsetBounds); to.offsetY = B.maxY(offsetBounds); B.move(to, -to.offsetX, -to.offsetY); }, scale(t, scaleX, scaleY = scaleX, onlySize) { onlySize || PointHelper.scale(t, scaleX, scaleY); t.width *= scaleX; t.height *= scaleY; }, scaleOf(t, origin, scaleX, scaleY = scaleX) { PointHelper.scaleOf(t, origin, scaleX, scaleY); t.width *= scaleX; t.height *= scaleY; }, tempToOuterOf(t, matrix) { B.copy(tempBounds$3, t); B.toOuterOf(tempBounds$3, matrix); return tempBounds$3; }, getOuterOf(t, matrix) { t = Object.assign({}, t); B.toOuterOf(t, matrix); return t; }, toOuterOf(t, matrix, to) { to || (to = t); if (matrix.b === 0 && matrix.c === 0) { const {a: a, d: d} = matrix; if (a > 0) { to.width = t.width * a; to.x = matrix.e + t.x * a; } else { to.width = t.width * -a; to.x = matrix.e + t.x * a - to.width; } if (d > 0) { to.height = t.height * d; to.y = matrix.f + t.y * d; } else { to.height = t.height * -d; to.y = matrix.f + t.y * d - to.height; } } else { point$1.x = t.x; point$1.y = t.y; toOuterPoint$2(matrix, point$1, toPoint$5); setPoint$5(tempPointBounds$1, toPoint$5.x, toPoint$5.y); point$1.x = t.x + t.width; toOuterPoint$2(matrix, point$1, toPoint$5); addPoint$3(tempPointBounds$1, toPoint$5.x, toPoint$5.y); point$1.y = t.y + t.height; toOuterPoint$2(matrix, point$1, toPoint$5); addPoint$3(tempPointBounds$1, toPoint$5.x, toPoint$5.y); point$1.x = t.x; toOuterPoint$2(matrix, point$1, toPoint$5); addPoint$3(tempPointBounds$1, toPoint$5.x, toPoint$5.y); toBounds$3(tempPointBounds$1, to); } }, toInnerOf(t, matrix, to) { to || (to = t); B.move(to, -matrix.e, -matrix.f); B.scale(to, 1 / matrix.a, 1 / matrix.d); }, getFitMatrix(t, put, baseScale = 1) { const scale = Math.min(baseScale, B.getFitScale(t, put)); return new Matrix(scale, 0, 0, scale, -put.x * scale, -put.y * scale); }, getFitScale(t, put, isCoverMode) { const sw = t.width / put.width, sh = t.height / put.height; return isCoverMode ? Math.max(sw, sh) : Math.min(sw, sh); }, put(t, put, align = "center", putScale = 1, changeSize = true, to) { to || (to = put); if (isString(putScale)) putScale = B.getFitScale(t, put, putScale === "cover"); tempBounds$3.width = changeSize ? put.width *= putScale : put.width * putScale; tempBounds$3.height = changeSize ? put.height *= putScale : put.height * putScale; AlignHelper.toPoint(align, tempBounds$3, t, to, true, true); }, getSpread(t, spread, side) { const n = {}; B.copyAndSpread(n, t, spread, false, side); return n; }, spread(t, spread, side) { B.copyAndSpread(t, t, spread, false, side); }, shrink(t, shrink, side) { B.copyAndSpread(t, t, shrink, true, side); }, ceil(t) { const {x: x, y: y} = t; t.x = floor$2(t.x); t.y = floor$2(t.y); t.width = x > t.x ? ceil$2(t.width + x - t.x) : ceil$2(t.width); t.height = y > t.y ? ceil$2(t.height + y - t.y) : ceil$2(t.height); }, unsign(t) { if (t.width < 0) { t.x += t.width; t.width = -t.width; } if (t.height < 0) { t.y += t.height; t.height = -t.height; } }, float(t, maxLength) { t.x = float$1(t.x, maxLength); t.y = float$1(t.y, maxLength); t.width = float$1(t.width, maxLength); t.height = float$1(t.height, maxLength); }, add(t, bounds, isPoint) { right$4 = t.x + t.width; bottom$3 = t.y + t.height; boundsRight = bounds.x; boundsBottom = bounds.y; if (!isPoint) { boundsRight += bounds.width; boundsBottom += bounds.height; } right$4 = right$4 > boundsRight ? right$4 : boundsRight; bottom$3 = bottom$3 > boundsBottom ? bottom$3 : boundsBottom; t.x = t.x < bounds.x ? t.x : bounds.x; t.y = t.y < bounds.y ? t.y : bounds.y; t.width = right$4 - t.x; t.height = bottom$3 - t.y; }, addList(t, list) { B.setListWithFn(t, list, undefined, true); }, setList(t, list, addMode = false) { B.setListWithFn(t, list, undefined, addMode); }, addListWithFn(t, list, boundsDataFn) { B.setListWithFn(t, list, boundsDataFn, true); }, setListWithFn(t, list, boundsDataFn, addMode = false) { let bounds, first = true; for (let i = 0, len = list.length; i < len; i++) { bounds = boundsDataFn ? boundsDataFn(list[i], i) : list[i]; if (bounds && (bounds.width || bounds.height)) { if (first) { first = false; if (!addMode) copy$c(t, bounds); } else { add$2(t, bounds); } } } if (first) B.reset(t); }, setPoints(t, points) { points.forEach((point, index) => index === 0 ? setPoint$5(tempPointBounds$1, point.x, point.y) : addPoint$3(tempPointBounds$1, point.x, point.y)); toBounds$3(tempPointBounds$1, t); }, setPoint(t, point) { B.set(t, point.x, point.y); }, addPoint(t, point) { add$2(t, point, true); }, getPoints(t) { const {x: x, y: y, width: width, height: height} = t; return [ { x: x, y: y }, { x: x + width, y: y }, { x: x + width, y: y + height }, { x: x, y: y + height } ]; }, hitRadiusPoint(t, point, pointMatrix) { if (pointMatrix) point = PointHelper.tempToInnerRadiusPointOf(point, pointMatrix); return point.x >= t.x - point.radiusX && point.x <= t.x + t.width + point.radiusX && (point.y >= t.y - point.radiusY && point.y <= t.y + t.height + point.radiusY); }, hitPoint(t, point, pointMatrix) { if (pointMatrix) point = PointHelper.tempToInnerOf(point, pointMatrix); return point.x >= t.x && point.x <= t.x + t.width && (point.y >= t.y && point.y <= t.y + t.height); }, hit(t, other, otherMatrix) { if (otherMatrix) other = B.tempToOuterOf(other, otherMatrix); return !(t.y + t.height < other.y || other.y + other.height < t.y || t.x + t.width < other.x || other.x + other.width < t.x); }, includes(t, other, otherMatrix) { if (otherMatrix) other = B.tempToOuterOf(other, otherMatrix); return t.x <= other.x && t.y <= other.y && t.x + t.width >= other.x + other.width && t.y + t.height >= other.y + other.height; }, getIntersectData(t, other, otherMatrix) { if (otherMatrix) other = B.tempToOuterOf(other, otherMatrix); if (!B.hit(t, other)) return getBoundsData(); let {x: x, y: y, width: width, height: height} = other; right$4 = x + width; bottom$3 = y + height; boundsRight = t.x + t.width; boundsBottom = t.y + t.height; x = x > t.x ? x : t.x; y = y > t.y ? y : t.y; right$4 = right$4 < boundsRight ? right$4 : boundsRight; bottom$3 = bottom$3 < boundsBottom ? bottom$3 : boundsBottom; width = right$4 - x; height = bottom$3 - y; return { x: x, y: y, width: width, height: height }; }, intersect(t, other, otherMatrix) { B.copy(t, B.getIntersectData(t, other, otherMatrix)); }, isSame(t, bounds) { return t.x === bounds.x && t.y === bounds.y && t.width === bounds.width && t.height === bounds.height; }, isEmpty(t) { return t.x === 0 && t.y === 0 && t.width === 0 && t.height === 0; }, reset(t) { B.set(t); } }; const B = BoundsHelper; const {add: add$2, copy: copy$c} = B; class Bounds { get minX() { return BoundsHelper.minX(this); } get minY() { return BoundsHelper.minY(this); } get maxX() { return BoundsHelper.maxX(this); } get maxY() { return BoundsHelper.maxY(this); } constructor(x, y, width, height) { this.set(x, y, width, height); } set(x, y, width, height) { isObject(x) ? BoundsHelper.copy(this, x) : BoundsHelper.set(this, x, y, width, height); return this; } get() { const {x: x, y: y, width: width, height: height} = this; return { x: x, y: y, width: width, height: height }; } clone() { return new Bounds(this); } move(x, y) { BoundsHelper.move(this, x, y); return this; } scale(scaleX, scaleY, onlySize) { BoundsHelper.scale(this, scaleX, scaleY, onlySize); return this; } scaleOf(origin, scaleX, scaleY) { BoundsHelper.scaleOf(this, origin, scaleX, scaleY); return this; } toOuterOf(matrix, to) { BoundsHelper.toOuterOf(this, matrix, to); return this; } toInnerOf(matrix, to) { BoundsHelper.toInnerOf(this, matrix, to); return this; } getFitMatrix(put, baseScale) { return BoundsHelper.getFitMatrix(this, put, baseScale); } put(put, align, putScale) { BoundsHelper.put(this, put, align, putScale); } spread(fourNumber, side) { BoundsHelper.spread(this, fourNumber, side); return this; } shrink(fourNumber, side) { BoundsHelper.shrink(this, fourNumber, side); return this; } ceil() { BoundsHelper.ceil(this); return this; } unsign() { BoundsHelper.unsign(this); return this; } float(maxLength) { BoundsHelper.float(this, maxLength); return this; } add(bounds) { BoundsHelper.add(this, bounds); return this; } addList(boundsList) { BoundsHelper.setList(this, boundsList, true); return this; } setList(boundsList) { BoundsHelper.setList(this, boundsList); return this; } addListWithFn(list, boundsDataFn) { BoundsHelper.setListWithFn(this, list, boundsDataFn, true); return this; } setListWithFn(list, boundsDataFn) { BoundsHelper.setListWithFn(this, list, boundsDataFn); return this; } setPoint(point) { BoundsHelper.setPoint(this, point); return this; } setPoints(points) { BoundsHelper.setPoints(this, points); return this; } addPoint(point) { BoundsHelper.addPoint(this, point); return this; } getPoints() { return BoundsHelper.getPoints(this); } hitPoint(point, pointMatrix) { return BoundsHelper.hitPoint(this, point, pointMatrix); } hitRadiusPoint(point, pointMatrix) { return BoundsHelper.hitRadiusPoint(this, point, pointMatrix); } hit(bounds, boundsMatrix) { return BoundsHelper.hit(this, bounds, boundsMatrix); } includes(bounds, boundsMatrix) { return BoundsHelper.includes(this, bounds, boundsMatrix); } intersect(bounds, boundsMatrix) { BoundsHelper.intersect(this, bounds, boundsMatrix); return this; } getIntersect(bounds, boundsMatrix) { return new Bounds(BoundsHelper.getIntersectData(this, bounds, boundsMatrix)); } isSame(bounds) { return BoundsHelper.isSame(this, bounds); } isEmpty() { return BoundsHelper.isEmpty(this); } reset() { BoundsHelper.reset(this); } } const tempBounds$2 = new Bounds; class AutoBounds { constructor(top, right, bottom, left, width, height) { isObject(top) ? this.copy(top) : this.set(top, right, bottom, left, width, height); } set(top = 0, right = 0, bottom = 0, left = 0, width = 0, height = 0) { this.top = top; this.right = right; this.bottom = bottom; this.left = left; this.width = width; this.height = height; } copy(autoSize) { const {top: top, right: right, bottom: bottom, left: left, width: width, hei