UNPKG

trtc-electron-sdk

Version:

trtc electron sdk

502 lines (501 loc) 25 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ResizeAnchorMode = void 0; const logger_1 = __importDefault(require("../logger")); var ResizeAnchorMode; (function (ResizeAnchorMode) { ResizeAnchorMode[ResizeAnchorMode["Both"] = 0] = "Both"; ResizeAnchorMode[ResizeAnchorMode["Corner"] = 1] = "Corner"; ResizeAnchorMode[ResizeAnchorMode["Edge"] = 2] = "Edge"; })(ResizeAnchorMode = exports.ResizeAnchorMode || (exports.ResizeAnchorMode = {})); const ResizeAnchorCSSClass = { topLeftAnchor: 'trtc-resizable-top-left-anchor', topAnchor: 'trtc-resizable-top-anchor', topRightAnchor: 'trtc-resizable-top-right-anchor', leftAnchor: 'trtc-resizable-left-anchor', rightAnchor: 'trtc-resizable-right-anchor', bottomLeftAnchor: 'trtc-resizable-bottom-left-anchor', bottomAnchor: 'trtc-resizable-bottom-anchor', bottomRightAnchor: 'trtc-resizable-bottom-right-anchor', }; const ResizeAnchorStyle = { resizeAnchor: { position: 'absolute', width: '0.5rem', height: '0.5rem', border: '1px solid transparent', backgroundColor: 'transparent' }, topLeftAnchor: { top: '0', left: '0', cursor: 'nw-resize' }, topAnchor: { top: '0', left: 'calc(50% - 0.25rem)', cursor: 'n-resize' }, topRightAnchor: { top: '0', right: '0', cursor: 'ne-resize' }, leftAnchor: { top: 'calc(50% - 0.25rem)', left: '0', cursor: 'w-resize' }, rightAnchor: { top: 'calc(50% - 0.25rem)', right: '0', cursor: 'e-resize' }, bottomLeftAnchor: { bottom: '0', left: '0', cursor: 'sw-resize' }, bottomAnchor: { bottom: '0', left: 'calc(50% - 0.25rem)', cursor: 's-resize' }, bottomRightAnchor: { bottom: '0', right: '0', cursor: 'se-resize' } }; function setElementStyle(el, styleOptions) { for (const key in styleOptions) { el.style[key] = styleOptions[key]; } } class Resizable { constructor(resizeTarget, container, options = { keepRatio: false, stopPropagation: false, anchorMode: ResizeAnchorMode.Both, canExceedContainer: false }) { this.logPrefix = '[Resizable]'; this.container = null; this.options = { keepRatio: false, stopPropagation: false, anchorMode: ResizeAnchorMode.Both, canExceedContainer: false }; this.callbacksMap = new Map(); this.topLeftAnchor = null; this.topAnchor = null; this.topRightAnchor = null; this.leftAnchor = null; this.rightAnchor = null; this.bottomLeftAnchor = null; this.bottomAnchor = null; this.bottomRightAnchor = null; this.currentAnchor = null; this.resizeStartLeft = 0; this.resizeStartTop = 0; this.originLeft = 0; this.originTop = 0; this.originWidth = 0; this.originHeight = 0; this.resizeTarget = resizeTarget; this.container = container || document.body; this.options = { keepRatio: !!options.keepRatio || false, stopPropagation: !!options.stopPropagation || false, anchorMode: options.anchorMode || ResizeAnchorMode.Both, canExceedContainer: !!options.canExceedContainer || false }; this.mousedown = this.mousedown.bind(this); this.mousemove = this.mousemove.bind(this); this.mouseup = this.mouseup.bind(this); this.currentAnchor = null; this.createResizeAnchor(); this.resizeTarget.classList.add("trtc-resizable"); this.resizeTarget.style.position = 'absolute'; this.resizeTarget.style.overflow = 'hidden'; this.initResizeEvent(); } createResizeAnchor() { var _a, _b, _c, _d, _e, _f, _g, _h; const topLeftAnchor = document.createElement("div"); topLeftAnchor.className = `trtc-resizable-resize-anchor ${ResizeAnchorCSSClass.topLeftAnchor}`; setElementStyle(topLeftAnchor, Object.assign({}, ResizeAnchorStyle.resizeAnchor, ResizeAnchorStyle.topLeftAnchor)); this.topLeftAnchor = topLeftAnchor; const topAnchor = document.createElement("div"); topAnchor.className = `trtc-resizable-resize-anchor ${ResizeAnchorCSSClass.topAnchor}`; setElementStyle(topAnchor, Object.assign({}, ResizeAnchorStyle.resizeAnchor, ResizeAnchorStyle.topAnchor)); this.topAnchor = topAnchor; const topRightAnchor = document.createElement("div"); topRightAnchor.className = `trtc-resizable-resize-anchor ${ResizeAnchorCSSClass.topRightAnchor}`; setElementStyle(topRightAnchor, Object.assign({}, ResizeAnchorStyle.resizeAnchor, ResizeAnchorStyle.topRightAnchor)); this.topRightAnchor = topRightAnchor; const leftAnchor = document.createElement("div"); leftAnchor.className = `trtc-resizable-resize-anchor ${ResizeAnchorCSSClass.leftAnchor}`; setElementStyle(leftAnchor, Object.assign({}, ResizeAnchorStyle.resizeAnchor, ResizeAnchorStyle.leftAnchor)); this.leftAnchor = leftAnchor; const rightAnchor = document.createElement("div"); rightAnchor.className = `trtc-resizable-resize-anchor ${ResizeAnchorCSSClass.rightAnchor}`; setElementStyle(rightAnchor, Object.assign({}, ResizeAnchorStyle.resizeAnchor, ResizeAnchorStyle.rightAnchor)); this.rightAnchor = rightAnchor; const bottomLeftAnchor = document.createElement("div"); bottomLeftAnchor.className = `trtc-resizable-resize-anchor ${ResizeAnchorCSSClass.bottomLeftAnchor}`; setElementStyle(bottomLeftAnchor, Object.assign({}, ResizeAnchorStyle.resizeAnchor, ResizeAnchorStyle.bottomLeftAnchor)); this.bottomLeftAnchor = bottomLeftAnchor; const bottomAnchor = document.createElement("div"); bottomAnchor.className = `trtc-resizable-resize-anchor ${ResizeAnchorCSSClass.bottomAnchor}`; setElementStyle(bottomAnchor, Object.assign({}, ResizeAnchorStyle.resizeAnchor, ResizeAnchorStyle.bottomAnchor)); this.bottomAnchor = bottomAnchor; const bottomRightAnchor = document.createElement("div"); bottomRightAnchor.className = `trtc-resizable-resize-anchor ${ResizeAnchorCSSClass.bottomRightAnchor}`; setElementStyle(bottomRightAnchor, Object.assign({}, ResizeAnchorStyle.resizeAnchor, ResizeAnchorStyle.bottomRightAnchor)); this.bottomRightAnchor = bottomRightAnchor; if (this.options.anchorMode === ResizeAnchorMode.Both || this.options.anchorMode === ResizeAnchorMode.Edge) { (_a = this.resizeTarget) === null || _a === void 0 ? void 0 : _a.appendChild(topAnchor); (_b = this.resizeTarget) === null || _b === void 0 ? void 0 : _b.appendChild(leftAnchor); (_c = this.resizeTarget) === null || _c === void 0 ? void 0 : _c.appendChild(rightAnchor); (_d = this.resizeTarget) === null || _d === void 0 ? void 0 : _d.appendChild(bottomAnchor); } if (this.options.anchorMode === ResizeAnchorMode.Both || this.options.anchorMode === ResizeAnchorMode.Corner) { (_e = this.resizeTarget) === null || _e === void 0 ? void 0 : _e.appendChild(topLeftAnchor); (_f = this.resizeTarget) === null || _f === void 0 ? void 0 : _f.appendChild(topRightAnchor); (_g = this.resizeTarget) === null || _g === void 0 ? void 0 : _g.appendChild(bottomLeftAnchor); (_h = this.resizeTarget) === null || _h === void 0 ? void 0 : _h.appendChild(bottomRightAnchor); } } initResizeEvent() { var _a, _b, _c, _d, _e, _f, _g, _h; (_a = this.topLeftAnchor) === null || _a === void 0 ? void 0 : _a.addEventListener("mousedown", this.mousedown, false); (_b = this.topAnchor) === null || _b === void 0 ? void 0 : _b.addEventListener("mousedown", this.mousedown, false); (_c = this.topRightAnchor) === null || _c === void 0 ? void 0 : _c.addEventListener("mousedown", this.mousedown, false); (_d = this.leftAnchor) === null || _d === void 0 ? void 0 : _d.addEventListener("mousedown", this.mousedown, false); (_e = this.rightAnchor) === null || _e === void 0 ? void 0 : _e.addEventListener("mousedown", this.mousedown, false); (_f = this.bottomLeftAnchor) === null || _f === void 0 ? void 0 : _f.addEventListener("mousedown", this.mousedown, false); (_g = this.bottomAnchor) === null || _g === void 0 ? void 0 : _g.addEventListener("mousedown", this.mousedown, false); (_h = this.bottomRightAnchor) === null || _h === void 0 ? void 0 : _h.addEventListener("mousedown", this.mousedown, false); } mousedown(event) { if (event.button !== 0) { return; } event.preventDefault(); // Avoid select text content. if (this.options.stopPropagation) { event.stopPropagation(); } this.currentAnchor = event.target; this.resizeStartLeft = event.screenX; this.resizeStartTop = event.screenY; if (document.defaultView && this.resizeTarget) { const resizeTargetStyle = document.defaultView.getComputedStyle(this.resizeTarget); this.originTop = window.parseInt(resizeTargetStyle.top); this.originLeft = window.parseInt(resizeTargetStyle.left); this.originWidth = this.resizeTarget.offsetWidth; this.originHeight = this.resizeTarget.offsetHeight; logger_1.default.debug("resize origin:", this.originTop, this.originLeft, this.originWidth, this.originHeight); } else { logger_1.default.error(`${this.logPrefix}mouseDown 'resizeTarget' is null`); } document.addEventListener("mousemove", this.mousemove, false); document.addEventListener("mouseup", this.mouseup, false); } mousemove(event) { if (!this.container || !this.resizeTarget || !this.currentAnchor) { logger_1.default.error(`${this.logPrefix}mouseMove error. No valid inner info:`, this.container, this.resizeTarget, this.currentAnchor); return; } const anchorType = this.currentAnchor.classList[1]; let left = this.originLeft, top = this.originTop, width = this.originWidth, height = this.originHeight; let result; switch (anchorType) { case ResizeAnchorCSSClass.topLeftAnchor: result = this._resizeTop(event); top = result.top; height = result.height; result = this._resizeLeft(event); left = result.left; width = result.width; if (this.options.keepRatio) { if (width / this.originWidth < height / this.originHeight) { // 宽度缩放比例小于高度缩放比例,保持当前宽度,调整高度 height = (width * this.originHeight) / this.originWidth; // 需要调整 y 坐标 top = this.originTop + this.originHeight - height; } else { // 高度缩放比例小于宽度缩放比例,保持当前高度,调整宽度 width = (height * this.originWidth) / this.originHeight; // 需要调整 x 坐标 left = this.originLeft + this.originWidth - width; } } break; case ResizeAnchorCSSClass.topAnchor: result = this._resizeTop(event); top = result.top; height = result.height; if (this.options.keepRatio) { width = this.originWidth * height / this.originHeight; if (width < 20) { width = 20; height = this.originHeight * width / this.originWidth; top = this.originTop + this.originHeight - height; } else if (!this.options.canExceedContainer && width > this.container.offsetWidth - this.originLeft) { width = this.container.offsetWidth - this.originLeft; height = this.originHeight * width / this.originWidth; top = this.originTop + this.originHeight - height; } } break; case ResizeAnchorCSSClass.topRightAnchor: result = this._resizeTop(event); top = result.top; height = result.height; width = this._resizeRight(event); if (this.options.keepRatio) { if (width / this.originWidth < height / this.originHeight) { height = (width * this.originHeight) / this.originWidth; top = this.originTop + this.originHeight - height; } else { width = (height * this.originWidth) / this.originHeight; } } break; case ResizeAnchorCSSClass.leftAnchor: result = this._resizeLeft(event); left = result.left; width = result.width; if (this.options.keepRatio) { height = this.originHeight * width / this.originWidth; if (height < 20) { height = 20; width = this.originWidth * height / this.originHeight; left = this.originLeft + this.originWidth - width; } else if (!this.options.canExceedContainer && height > this.container.offsetHeight - this.originTop) { height = this.container.offsetHeight - this.originTop; width = this.originWidth * height / this.originHeight; left = this.originLeft + this.originWidth - width; } } break; case ResizeAnchorCSSClass.rightAnchor: width = this._resizeRight(event); if (this.options.keepRatio) { height = (width * this.originHeight) / this.originWidth; if (height < 20) { height = 20; width = height * this.originWidth / this.originHeight; } else if (!this.options.canExceedContainer && height > this.container.offsetHeight - this.originTop) { height = this.container.offsetHeight - this.originTop; width = height * this.originWidth / this.originHeight; } } break; case ResizeAnchorCSSClass.bottomLeftAnchor: height = this._resizeBottom(event); result = this._resizeLeft(event); left = result.left; width = result.width; if (this.options.keepRatio) { if (width / this.originWidth < height / this.originHeight) { height = (width * this.originHeight) / this.originWidth; } else { width = (height * this.originWidth) / this.originHeight; left = this.originLeft + this.originWidth - width; } } break; case ResizeAnchorCSSClass.bottomAnchor: height = this._resizeBottom(event); if (this.options.keepRatio) { width = (height * this.originWidth) / this.originHeight; if (width < 20) { width = 20; height = width * this.originHeight / this.originWidth; } else if (!this.options.canExceedContainer && width > this.container.offsetWidth - this.originLeft) { width = this.container.offsetWidth - this.originLeft; height = width * this.originHeight / this.originWidth; } } break; case ResizeAnchorCSSClass.bottomRightAnchor: height = this._resizeBottom(event); width = this._resizeRight(event); if (this.options.keepRatio) { if (width / this.originWidth < height / this.originHeight) { height = (width * this.originHeight) / this.originWidth; } else { width = (height * this.originWidth) / this.originHeight; } } break; } this.resizeTarget.style.left = left + "px"; this.resizeTarget.style.top = top + "px"; this.resizeTarget.style.height = height + "px"; this.resizeTarget.style.width = width + "px"; this.emit("resize", left, top, width, height); } _resizeLeft(event) { const leftResizedDistance = event.screenX - this.resizeStartLeft; let left = this.originLeft + leftResizedDistance; let width = this.originWidth - leftResizedDistance; if (!this.options.canExceedContainer && left < 0) { left = 0; width = this.originWidth + this.originLeft; } else if (left > this.originLeft + this.originWidth - 20) { left = this.originLeft + this.originWidth - 20; width = 20; // 最小宽度 } return { left, width, }; } _resizeTop(event) { const topResizedDistance = event.screenY - this.resizeStartTop; let top = this.originTop + topResizedDistance; let height = this.originHeight - topResizedDistance; if (!this.options.canExceedContainer && top < 0) { top = 0; height = this.originHeight + this.originTop; } else if (top > this.originTop + this.originHeight - 20) { top = this.originTop + this.originHeight - 20; height = 20; // 最小高度 } return { top, height, }; } _resizeRight(event) { if (!this.container) { logger_1.default.error(`${this.logPrefix}_resizeRight error. No container:`, this.container); return 0; } const leftResizedDistance = event.screenX - this.resizeStartLeft; let width = this.originWidth + leftResizedDistance; if (width < 20) { width = 20; // 最小宽度 } else if (!this.options.canExceedContainer && width > this.container.offsetWidth - this.originLeft) { width = this.container.offsetWidth - this.originLeft; } return width; } _resizeBottom(event) { if (!this.container) { logger_1.default.error(`${this.logPrefix}_resizeBottom error. No container:`, this.container); return 0; } const topResizedDistance = event.screenY - this.resizeStartTop; let height = this.originHeight + topResizedDistance; if (height < 20) { height = 20; // 最小高度 } else if (!this.options.canExceedContainer && height > this.container.offsetHeight - this.originTop) { height = this.container.offsetHeight - this.originTop; } return height; } mouseup() { document.removeEventListener("mousemove", this.mousemove, false); document.removeEventListener("mouseup", this.mouseup, false); this.currentAnchor = null; this.resizeStartLeft = 0; this.resizeStartTop = 0; this.originLeft = 0; this.originTop = 0; this.originWidth = 0; this.originHeight = 0; } on(eventName, callback) { const callbacks = this.callbacksMap.get(eventName); if (callbacks) { callbacks.push(callback); } else { this.callbacksMap.set(eventName, [callback]); } } off(eventName, callback) { let callbacks = this.callbacksMap.get(eventName); if (callbacks) { callbacks = callbacks.filter((item) => item != callback); this.callbacksMap.set(eventName, callbacks); } } emit(eventName, ...arg) { const callbacks = this.callbacksMap.get(eventName); if (callbacks) { const callbacksClone = callbacks.slice(); callbacksClone.forEach((callback) => { try { callback.apply(null, arg); // arg must be array } catch (error) { console.error("[Resizable]emit error:", callback, error); } }); } } destroy() { var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r; (_a = this.topLeftAnchor) === null || _a === void 0 ? void 0 : _a.removeEventListener("mousedown", this.mousedown, false); (_b = this.topAnchor) === null || _b === void 0 ? void 0 : _b.removeEventListener("mousedown", this.mousedown, false); (_c = this.topRightAnchor) === null || _c === void 0 ? void 0 : _c.removeEventListener("mousedown", this.mousedown, false); (_d = this.leftAnchor) === null || _d === void 0 ? void 0 : _d.removeEventListener("mousedown", this.mousedown, false); (_e = this.rightAnchor) === null || _e === void 0 ? void 0 : _e.removeEventListener("mousedown", this.mousedown, false); (_f = this.bottomLeftAnchor) === null || _f === void 0 ? void 0 : _f.removeEventListener("mousedown", this.mousedown, false); (_g = this.bottomAnchor) === null || _g === void 0 ? void 0 : _g.removeEventListener("mousedown", this.mousedown, false); (_h = this.bottomRightAnchor) === null || _h === void 0 ? void 0 : _h.removeEventListener("mousedown", this.mousedown, false); this.callbacksMap.clear(); if (this.options.anchorMode === ResizeAnchorMode.Both || this.options.anchorMode === ResizeAnchorMode.Edge) { this.topAnchor && ((_j = this.resizeTarget) === null || _j === void 0 ? void 0 : _j.removeChild(this.topAnchor)); this.leftAnchor && ((_k = this.resizeTarget) === null || _k === void 0 ? void 0 : _k.removeChild(this.leftAnchor)); this.rightAnchor && ((_l = this.resizeTarget) === null || _l === void 0 ? void 0 : _l.removeChild(this.rightAnchor)); this.bottomAnchor && ((_m = this.resizeTarget) === null || _m === void 0 ? void 0 : _m.removeChild(this.bottomAnchor)); } if (this.options.anchorMode === ResizeAnchorMode.Both || this.options.anchorMode === ResizeAnchorMode.Corner) { this.topLeftAnchor && ((_o = this.resizeTarget) === null || _o === void 0 ? void 0 : _o.removeChild(this.topLeftAnchor)); this.topRightAnchor && ((_p = this.resizeTarget) === null || _p === void 0 ? void 0 : _p.removeChild(this.topRightAnchor)); this.bottomLeftAnchor && ((_q = this.resizeTarget) === null || _q === void 0 ? void 0 : _q.removeChild(this.bottomLeftAnchor)); this.bottomRightAnchor && ((_r = this.resizeTarget) === null || _r === void 0 ? void 0 : _r.removeChild(this.bottomRightAnchor)); } this.topLeftAnchor = null; this.topAnchor = null; this.topRightAnchor = null; this.leftAnchor = null; this.rightAnchor = null; this.bottomLeftAnchor = null; this.bottomAnchor = null; this.bottomRightAnchor = null; this.resizeTarget = null; this.container = null; this.currentAnchor = null; this.resizeStartLeft = 0; this.resizeStartTop = 0; this.originLeft = 0; this.originTop = 0; this.originWidth = 0; this.originHeight = 0; } } exports.default = Resizable;