UNPKG

vue-frame-selection

Version:
422 lines (421 loc) 13.9 kB
import Vue from "vue"; function isDOMType(value) { return isDOM(value); } function isDocument(value) { return (value == null ? void 0 : value.nodeName) === "#document"; } function scaleRect(rect, scale) { if (scale === 1) { return rect; } return { left: rect.left * scale, top: rect.top * scale, width: rect.width * scale, height: rect.height * scale, right: rect.right * scale, bottom: rect.bottom * scale }; } const rectangleElementInlineStyle = "position: absolute;pointer-events: none;border: 1px solid rgb(45, 140, 240);background: rgba(45, 140, 240, 0.2);display:none;"; const getInitCustomRect = () => ({ left: 0, top: 0, width: 0, height: 0, right: 0, bottom: 0 }); class MouseSelection { constructor(domOrConfig, config) { var _a; this.domRect = getInitCustomRect(); this.selectionPagePositionRect = getInitCustomRect(); this.selectionDOMPositionRect = getInitCustomRect(); this.startX = 0; this.startY = 0; this.scale = 1; this.moving = false; this.RectangleElementClassName = "frame-selection-rectangle-element"; this._selectStart = (event) => { var _a2, _b, _c, _d, _e, _f; const nodeList = this.targetDom.querySelectorAll(this.config.stopSelector); const isStopNode = findNode(event.target, Array.from(nodeList)); if (this.config.stopSelector && isStopNode) { return; } if ((_a2 = this.config) == null ? void 0 : _a2.stopPropagation) { event.stopPropagation(); } if (event.button !== 0) { return; } if (((_b = this.config) == null ? void 0 : _b.disabled) && ((_c = this.config) == null ? void 0 : _c.disabled())) { return; } this.rectangleElement = this._createRectangleElement(); this.moving = true; this.domRect = this._getDOMRect(this.targetDom); const x = (event.pageX + ((_d = this.wrapDOM) == null ? void 0 : _d.scrollLeft) - window.pageXOffset) / this.scale; const y = (event.pageY + ((_e = this.wrapDOM) == null ? void 0 : _e.scrollTop) - window.pageYOffset) / this.scale; this._setStartPosition(x - 2, y - 2); this.selectionPagePositionRect = this.getSelectionPagePosition(x, y); this.selectionDOMPositionRect = this.getSelectionDOMPosition(this.selectionPagePositionRect); this._updateRectangleElementStyle(this.selectionDOMPositionRect); const callback = (_f = this.config) == null ? void 0 : _f.onMousedown; callback && callback(event); document.addEventListener("mouseup", this._selectEnd); document.addEventListener("mousemove", this._selecting); }; this._selecting = (event) => { var _a2, _b, _c; if (!this.moving) { return; } const x = (event.pageX + ((_a2 = this.wrapDOM) == null ? void 0 : _a2.scrollLeft) - window.pageXOffset) / this.scale; const y = (event.pageY + ((_b = this.wrapDOM) == null ? void 0 : _b.scrollTop) - window.pageYOffset) / this.scale; this.selectionPagePositionRect = this.getSelectionPagePosition(x, y); this._setRectangleElementStyle("display", "block"); const refitedMouseEvent = event; this.selectionDOMPositionRect = this.getSelectionDOMPosition(this.selectionPagePositionRect); refitedMouseEvent.selectionDOMRect = JSON.parse(JSON.stringify(this.selectionDOMPositionRect)); this._updateRectangleElementStyle(this.selectionDOMPositionRect); const callback = (_c = this.config) == null ? void 0 : _c.onMousemove; callback && callback(refitedMouseEvent); }; this._selectEnd = (event) => { var _a2; document.removeEventListener("mousemove", this._selecting); document.removeEventListener("mouseup", this._selectEnd); this._setRectangleElementStyle("display", "none"); this.moving = false; const callback = (_a2 = this.config) == null ? void 0 : _a2.onMouseup; callback && callback(event); }; let dom = document; this.config = config; if (isDOMType(domOrConfig)) { dom = domOrConfig; } else if (domOrConfig) { this.config = domOrConfig; } this.targetDom = dom; if (isDocument(this.targetDom)) { this.wrapDOM = document.body; } else { this.wrapDOM = this.targetDom; } this.scale = ((_a = this.config) == null ? void 0 : _a.scale) || 1; this._setWrapDomPositionStyle(); this._addMousedownListener(this.targetDom); } getSelectionPagePosition(x, y) { var _a, _b; const domRect = this.domRect; x = x - 2; y = y - 2; const left = Math.max(domRect.left, Math.min(this.startX, x)); const top = Math.max(domRect.top, Math.min(this.startY, y)); const width = Math.max(this.startX, Math.min(x, ((_a = this.wrapDOM) == null ? void 0 : _a.scrollWidth) + domRect.left - 2)) - left; const height = Math.max(this.startY, Math.min(y, ((_b = this.wrapDOM) == null ? void 0 : _b.scrollHeight) + domRect.top - 2)) - top; return { left, top, width, height, right: left + width, bottom: top + height }; } getSelectionDOMPosition(selectionPagePositionRect) { const { left, top, width, height, right, bottom } = selectionPagePositionRect; const { left: DOMLeft, top: DOMTop } = this.domRect; return { left: left - DOMLeft, top: top - DOMTop, width, height, right: right - DOMLeft, bottom: bottom - DOMTop }; } isInTheSelection({ left, top, width, height }) { const { left: x, top: y, width: w, height: h } = this.selectionDOMPositionRect; return left + width > x && x + w > left && top + height > y && y + h > top; } destroy() { this.rectangleElement && this.wrapDOM.removeChild(this.rectangleElement); this._removeMousedownListener(this.targetDom); this.rectangleElement = null; this.targetDom = null; this.domRect = null; this.selectionPagePositionRect = null; this.selectionDOMPositionRect = null; this.startX = null; this.startY = null; this.moving = null; this.wrapDOM = null; } _setWrapDomPositionStyle() { var _a; if ((_a = this.config) == null ? void 0 : _a.notSetWrapPosition) { return; } const position = getComputedStyle(this.wrapDOM).position; if (position === "static") { this.wrapDOM.style.position = "relative"; } } _createRectangleElement() { var _a, _b, _c, _d, _e; let ele = Array.from((_a = this.wrapDOM) == null ? void 0 : _a.children).find((node) => Array.from(node.classList).includes(this.RectangleElementClassName)); if (ele) { (_b = this.wrapDOM) == null ? void 0 : _b.removeChild(ele); } ele = document.createElement("div"); const customClassName = (_c = this.config) == null ? void 0 : _c.className; ele.className = this.RectangleElementClassName + (customClassName ? ` ${customClassName}` : ""); ele.style.cssText = rectangleElementInlineStyle + `z-index: ${((_d = this.config) == null ? void 0 : _d.zIndex) || 99999999}`; (_e = this.wrapDOM) == null ? void 0 : _e.appendChild(ele); return ele; } _setStartPosition(x, y) { this.startX = x; this.startY = y; } _addMousedownListener(dom) { dom == null ? void 0 : dom.addEventListener("mousedown", this._selectStart); } _removeMousedownListener(dom) { dom == null ? void 0 : dom.removeEventListener("mousedown", this._selectStart); } _getDOMRect(dom) { const domRect = isDocument(dom) ? { left: 0, top: 0, width: window.innerWidth, height: window.innerHeight, right: window.innerWidth, bottom: window.innerHeight } : dom == null ? void 0 : dom.getBoundingClientRect(); return scaleRect(domRect, 1 / this.scale); } _setRectangleElementStyle(props, value) { this.rectangleElement.style[props] = value; } _updateRectangleElementStyle(rect) { const { left, top, width, height } = rect; this._setRectangleElementStyle("left", `${left}px`); this._setRectangleElementStyle("top", `${top}px`); this._setRectangleElementStyle("width", `${width}px`); this._setRectangleElementStyle("height", `${height}px`); } } function isDOM(object) { if (!object || typeof object !== "object") { return false; } if (typeof HTMLElement === "function") { return object instanceof HTMLElement || object instanceof Document; } else { return object && typeof object === "object" && object.nodeType && typeof object.nodeName === "string"; } } function findNode(target, nodeList) { if (nodeList.some((node) => target === node)) { return true; } else { if (target.parentNode) { return findNode(target.parentNode, nodeList); } else { return false; } } } var __vue2_script$1 = Vue.extend({ name: "FrameSelectionGroup", componentName: "SomFrameSelectionGroup", provide() { return { SomFrameSelection: this }; }, props: { className: { type: [String] }, scale: { type: [Number] }, zIndex: { type: [Number] }, disabled: { type: [Boolean] }, stopPropagation: { type: [Boolean] }, stopSelector: { type: [String] }, notSetWrapPosition: { type: [Boolean] } }, data() { const fields = []; const selection = null; return { selection, fields }; }, computed: { cacheDoms() { return this.fields.map((x) => x.$refs.dom); } }, methods: { isInTheSelection(rect) { if (this.selection) { return this.selection.isInTheSelection(rect); } }, getInnerBoxRectList() { return this.cacheDoms.map((dom) => { return { left: dom.offsetLeft, top: dom.offsetTop, width: dom.offsetWidth, height: dom.offsetHeight }; }); } }, mounted() { this.selection = new MouseSelection(this.$refs.wrap, { onMousedown: (e) => { this.$emit("mousedown", e); }, onMousemove: (e) => { this.$emit("mousemove", e); }, onMouseup: (e) => { this.$emit("mouseup", e); }, className: this.className, disabled: () => { return this.disabled; }, stopSelector: this.stopSelector, stopPropagation: this.stopPropagation, notSetWrapPosition: this.notSetWrapPosition, scale: this.scale, zIndex: this.zIndex }); } }); var render$1 = function() { var _vm = this; var _h = _vm.$createElement; var _c = _vm._self._c || _h; return _c("div", { ref: "wrap", staticClass: "som-frame-selection-group-wrapper" }, [_vm._t("default")], 2); }; var staticRenderFns$1 = []; function normalizeComponent(scriptExports, render2, staticRenderFns2, functionalTemplate, injectStyles, scopeId, moduleIdentifier, shadowMode) { var options = typeof scriptExports === "function" ? scriptExports.options : scriptExports; if (render2) { options.render = render2; options.staticRenderFns = staticRenderFns2; options._compiled = true; } if (functionalTemplate) { options.functional = true; } if (scopeId) { options._scopeId = "data-v-" + scopeId; } var hook; if (moduleIdentifier) { hook = function(context) { context = context || this.$vnode && this.$vnode.ssrContext || this.parent && this.parent.$vnode && this.parent.$vnode.ssrContext; if (!context && typeof __VUE_SSR_CONTEXT__ !== "undefined") { context = __VUE_SSR_CONTEXT__; } if (injectStyles) { injectStyles.call(this, context); } if (context && context._registeredComponents) { context._registeredComponents.add(moduleIdentifier); } }; options._ssrRegister = hook; } else if (injectStyles) { hook = shadowMode ? function() { injectStyles.call(this, (options.functional ? this.parent : this).$root.$options.shadowRoot); } : injectStyles; } if (hook) { if (options.functional) { options._injectStyles = hook; var originalRender = options.render; options.render = function renderWithStyleInjection(h, context) { hook.call(context); return originalRender(h, context); }; } else { var existing = options.beforeCreate; options.beforeCreate = existing ? [].concat(existing, hook) : [hook]; } } return { exports: scriptExports, options }; } const __cssModules$1 = {}; var __component__$1 = /* @__PURE__ */ normalizeComponent(__vue2_script$1, render$1, staticRenderFns$1, false, __vue2_injectStyles$1, null, null, null); function __vue2_injectStyles$1(context) { for (let o in __cssModules$1) { this[o] = __cssModules$1[o]; } } var group = /* @__PURE__ */ function() { return __component__$1.exports; }(); var __vue2_script = Vue.extend({ name: "FrameSelectionItem", componentName: "SomFrameSelectionItem", inject: ["SomFrameSelection"], mounted() { this.SomFrameSelection.fields.push(this); }, beforeDestroy() { this.SomFrameSelection.fields.splice(this.SomFrameSelection.fields.indexOf(this), 1); } }); var render = function() { var _vm = this; var _h = _vm.$createElement; var _c = _vm._self._c || _h; return _c("div", { ref: "dom", staticClass: "som-frame-selection-inner-box" }, [_vm._t("default")], 2); }; var staticRenderFns = []; const __cssModules = {}; var __component__ = /* @__PURE__ */ normalizeComponent(__vue2_script, render, staticRenderFns, false, __vue2_injectStyles, null, null, null); function __vue2_injectStyles(context) { for (let o in __cssModules) { this[o] = __cssModules[o]; } } var item = /* @__PURE__ */ function() { return __component__.exports; }(); export { group as FrameSelectionGroup, item as FrameSelectionItem, MouseSelection };