UNPKG

trtc-electron-sdk

Version:

trtc electron sdk

529 lines (528 loc) 26 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 constant_1 = require("../constant"); 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 DefaultHighlightColor = `#${constant_1.DEFAULT_HIGHLIGHT_COLOR.toString(16).padStart(6, '0')}`; 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: '8px', height: '8px', border: `1px solid ${DefaultHighlightColor}`, backgroundColor: DefaultHighlightColor }, topLeftAnchor: { top: '-4px', left: '-4px', cursor: 'nw-resize' }, topAnchor: { top: '-4px', left: 'calc(50% - 4px)', cursor: 'n-resize' }, topRightAnchor: { top: '-4px', right: '-4px', cursor: 'ne-resize' }, leftAnchor: { top: 'calc(50% - 4px)', left: '-4px', cursor: 'w-resize' }, rightAnchor: { top: 'calc(50% - 4px)', right: '-4px', cursor: 'e-resize' }, bottomLeftAnchor: { bottom: '-4px', left: '-4px', cursor: 'sw-resize' }, bottomAnchor: { bottom: '-4px', left: 'calc(50% - 4px)', cursor: 's-resize' }, bottomRightAnchor: { bottom: '-4px', right: '-4px', 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, hightlightColor: DefaultHighlightColor, }) { this.logPrefix = '[Resizable]'; this.container = null; this.options = { keepRatio: false, stopPropagation: false, anchorMode: ResizeAnchorMode.Both, canExceedContainer: false, hightlightColor: DefaultHighlightColor, }; 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, hightlightColor: options.hightlightColor || DefaultHighlightColor, }; this.mousedown = this.mousedown.bind(this); this.mousemove = this.mousemove.bind(this); this.mouseup = this.mouseup.bind(this); this.currentAnchor = null; ResizeAnchorStyle.resizeAnchor.border = `1px solid ${this.options.hightlightColor}`; ResizeAnchorStyle.resizeAnchor.backgroundColor = this.options.hightlightColor; this.createResizeAnchor(); this.resizeTarget.classList.add("trtc-resizable"); this.resizeTarget.style.position = 'absolute'; this.resizeTarget.style.border = `1px solid ${this.options.hightlightColor}`; this.initResizeEvent(); } setHighlightColor(color) { if (color !== this.options.hightlightColor) { this.options.hightlightColor = color; ResizeAnchorStyle.resizeAnchor.border = `1px solid ${this.options.hightlightColor}`; ResizeAnchorStyle.resizeAnchor.backgroundColor = this.options.hightlightColor; if (this.resizeTarget) { this.resizeTarget.style.border = `1px solid ${this.options.hightlightColor}`; } this.setResizeAnchorStyle(); } } createResizeAnchor() { var _a, _b, _c, _d, _e, _f, _g, _h; const topLeftAnchor = document.createElement("div"); topLeftAnchor.className = `trtc-resizable-resize-anchor ${ResizeAnchorCSSClass.topLeftAnchor}`; this.topLeftAnchor = topLeftAnchor; const topAnchor = document.createElement("div"); topAnchor.className = `trtc-resizable-resize-anchor ${ResizeAnchorCSSClass.topAnchor}`; this.topAnchor = topAnchor; const topRightAnchor = document.createElement("div"); topRightAnchor.className = `trtc-resizable-resize-anchor ${ResizeAnchorCSSClass.topRightAnchor}`; this.topRightAnchor = topRightAnchor; const leftAnchor = document.createElement("div"); leftAnchor.className = `trtc-resizable-resize-anchor ${ResizeAnchorCSSClass.leftAnchor}`; this.leftAnchor = leftAnchor; const rightAnchor = document.createElement("div"); rightAnchor.className = `trtc-resizable-resize-anchor ${ResizeAnchorCSSClass.rightAnchor}`; this.rightAnchor = rightAnchor; const bottomLeftAnchor = document.createElement("div"); bottomLeftAnchor.className = `trtc-resizable-resize-anchor ${ResizeAnchorCSSClass.bottomLeftAnchor}`; this.bottomLeftAnchor = bottomLeftAnchor; const bottomAnchor = document.createElement("div"); bottomAnchor.className = `trtc-resizable-resize-anchor ${ResizeAnchorCSSClass.bottomAnchor}`; this.bottomAnchor = bottomAnchor; const bottomRightAnchor = document.createElement("div"); bottomRightAnchor.className = `trtc-resizable-resize-anchor ${ResizeAnchorCSSClass.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); } this.setResizeAnchorStyle(); } setResizeAnchorStyle() { const anchorMappings = [ { anchor: this.topLeftAnchor, style: ResizeAnchorStyle.topLeftAnchor }, { anchor: this.topAnchor, style: ResizeAnchorStyle.topAnchor }, { anchor: this.topRightAnchor, style: ResizeAnchorStyle.topRightAnchor }, { anchor: this.leftAnchor, style: ResizeAnchorStyle.leftAnchor }, { anchor: this.rightAnchor, style: ResizeAnchorStyle.rightAnchor }, { anchor: this.bottomLeftAnchor, style: ResizeAnchorStyle.bottomLeftAnchor }, { anchor: this.bottomAnchor, style: ResizeAnchorStyle.bottomAnchor }, { anchor: this.bottomRightAnchor, style: ResizeAnchorStyle.bottomRightAnchor } ]; anchorMappings.forEach(mapping => { if (mapping.anchor) { setElementStyle(mapping.anchor, Object.assign({}, ResizeAnchorStyle.resizeAnchor, mapping.style)); } }); } 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; } 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;