UNPKG

vue-draggable-resizable

Version:
528 lines (527 loc) 20.4 kB
import { openBlock as z, createElementBlock as v, normalizeStyle as H, normalizeClass as T, Fragment as E, renderList as L, withModifiers as B, renderSlot as k } from "vue"; function D(t) { return typeof t == "function" || Object.prototype.toString.call(t) === "[object Function]"; } function w(t, e, i, s = 1) { const [h, o] = typeof s == "number" ? [s, s] : s, a = Math.round(e / h / t[0]) * t[0], l = Math.round(i / o / t[1]) * t[1]; return [a, l]; } function R(t, e, i) { return t - e - i; } function S(t, e, i) { return t - e - i; } function c(t, e, i) { return e !== null && t < e ? e : i !== null && i < t ? i : t; } function W(t, e, i) { let s = t; const h = [ "matches", "webkitMatchesSelector", "mozMatchesSelector", "msMatchesSelector", "oMatchesSelector" ].find((o) => D(s[o])); if (!D(s[h])) return !1; do { if (s[h](e)) return !0; if (s === i) return !1; s = s.parentNode; } while (s); return !1; } function N(t) { const e = window.getComputedStyle(t); return [ parseFloat(e.getPropertyValue("width"), 10), parseFloat(e.getPropertyValue("height"), 10) ]; } function b(t, e, i) { t && (t.attachEvent ? t.attachEvent("on" + e, i) : t.addEventListener ? t.addEventListener(e, i, !0) : t["on" + e] = i); } function f(t, e, i) { t && (t.detachEvent ? t.detachEvent("on" + e, i) : t.removeEventListener ? t.removeEventListener(e, i, !0) : t["on" + e] = null); } const P = (t, e) => { const i = t.__vccOpts || t; for (const [s, h] of e) i[s] = h; return i; }, y = { mouse: { start: "mousedown", move: "mousemove", stop: "mouseup" }, touch: { start: "touchstart", move: "touchmove", stop: "touchend" } }, C = { userSelect: "none", MozUserSelect: "none", WebkitUserSelect: "none", MsUserSelect: "none" }, X = { userSelect: "auto", MozUserSelect: "auto", WebkitUserSelect: "auto", MsUserSelect: "auto" }; let p = y.mouse; const Y = { replace: !0, name: "vue-draggable-resizable", props: { className: { type: String, default: "vdr" }, classNameDraggable: { type: String, default: "draggable" }, classNameResizable: { type: String, default: "resizable" }, classNameDragging: { type: String, default: "dragging" }, classNameResizing: { type: String, default: "resizing" }, classNameActive: { type: String, default: "active" }, classNameHandle: { type: String, default: "handle" }, disableUserSelect: { type: Boolean, default: !0 }, enableNativeDrag: { type: Boolean, default: !1 }, preventDeactivation: { type: Boolean, default: !1 }, active: { type: Boolean, default: !1 }, draggable: { type: Boolean, default: !0 }, resizable: { type: Boolean, default: !0 }, lockAspectRatio: { type: Boolean, default: !1 }, w: { type: [Number, String], default: 200, validator: (t) => typeof t == "number" ? t > 0 : t === "auto" }, h: { type: [Number, String], default: 200, validator: (t) => typeof t == "number" ? t > 0 : t === "auto" }, minWidth: { type: Number, default: 0, validator: (t) => t >= 0 }, minHeight: { type: Number, default: 0, validator: (t) => t >= 0 }, maxWidth: { type: Number, default: null, validator: (t) => t >= 0 }, maxHeight: { type: Number, default: null, validator: (t) => t >= 0 }, x: { type: Number, default: 0 }, y: { type: Number, default: 0 }, z: { type: [String, Number], default: "auto", validator: (t) => typeof t == "string" ? t === "auto" : t >= 0 }, handles: { type: Array, default: () => ["tl", "tm", "tr", "mr", "br", "bm", "bl", "ml"], validator: (t) => { const e = /* @__PURE__ */ new Set(["tl", "tm", "tr", "mr", "br", "bm", "bl", "ml"]); return new Set(t.filter((i) => e.has(i))).size === t.length; } }, dragHandle: { type: String, default: null }, dragCancel: { type: String, default: null }, axis: { type: String, default: "both", validator: (t) => ["x", "y", "both"].includes(t) }, grid: { type: Array, default: () => [1, 1] }, parent: { type: Boolean, default: !1 }, scale: { type: [Number, Array], default: 1, validator: (t) => typeof t == "number" ? t > 0 : t.length === 2 && t[0] > 0 && t[1] > 0 }, onDragStart: { type: Function, default: () => !0 }, onDrag: { type: Function, default: () => !0 }, onResizeStart: { type: Function, default: () => !0 }, onResize: { type: Function, default: () => !0 } }, data: function() { return { left: this.x, top: this.y, right: null, bottom: null, width: null, height: null, widthTouched: !1, heightTouched: !1, aspectFactor: null, parentWidth: null, parentHeight: null, handle: null, enabled: this.active, resizing: !1, dragging: !1, dragEnable: !1, resizeEnable: !1, zIndex: this.z }; }, created: function() { this.maxWidth && this.minWidth > this.maxWidth && console.warn("[Vdr warn]: Invalid prop: minWidth cannot be greater than maxWidth"), this.maxHeight && this.minHeight > this.maxHeight && console.warn("[Vdr warn]: Invalid prop: minHeight cannot be greater than maxHeight"), this.resetBoundsAndMouseState(); }, mounted: function() { this.enableNativeDrag || (this.$el.ondragstart = () => !1); const [t, e] = this.getParentSize(); this.parentWidth = t, this.parentHeight = e; const [i, s] = N(this.$el); this.aspectFactor = (this.w !== "auto" ? this.w : i) / (this.h !== "auto" ? this.h : s), this.width = this.w !== "auto" ? this.w : i, this.height = this.h !== "auto" ? this.h : s, this.right = this.parentWidth - this.width - this.left, this.bottom = this.parentHeight - this.height - this.top, this.active && this.$emit("activated"), b(document.documentElement, "mousedown", this.deselect), b(document.documentElement, "touchend touchcancel", this.deselect), b(window, "resize", this.checkParentSize); }, beforeUnmount: function() { f(document.documentElement, "mousedown", this.deselect), f(document.documentElement, "touchstart", this.handleUp), f(document.documentElement, "mousemove", this.move), f(document.documentElement, "touchmove", this.move), f(document.documentElement, "mouseup", this.handleUp), f(document.documentElement, "touchend touchcancel", this.deselect), f(window, "resize", this.checkParentSize); }, methods: { resetBoundsAndMouseState() { this.mouseClickPosition = { mouseX: 0, mouseY: 0, x: 0, y: 0, w: 0, h: 0 }, this.bounds = { minLeft: null, maxLeft: null, minRight: null, maxRight: null, minTop: null, maxTop: null, minBottom: null, maxBottom: null }; }, checkParentSize() { if (this.parent) { const [t, e] = this.getParentSize(); this.parentWidth = t, this.parentHeight = e, this.right = this.parentWidth - this.width - this.left, this.bottom = this.parentHeight - this.height - this.top; } }, getParentSize() { if (this.parent) { const t = window.getComputedStyle(this.$el.parentNode, null); return [ parseInt(t.getPropertyValue("width"), 10), parseInt(t.getPropertyValue("height"), 10) ]; } return [null, null]; }, elementTouchDown(t) { p = y.touch, this.elementDown(t); }, elementMouseDown(t) { p = y.mouse, this.elementDown(t); }, elementDown(t) { if (t instanceof MouseEvent && t.button !== 0) return; const e = t.target || t.srcElement; if (this.$el.contains(e)) { if (this.onDragStart(t) === !1) return; if (this.dragHandle && !W(e, this.dragHandle, this.$el) || this.dragCancel && W(e, this.dragCancel, this.$el)) { this.dragging = !1; return; } this.enabled || (this.enabled = !0, this.$emit("activated"), this.$emit("update:active", !0)), this.draggable && (this.dragEnable = !0), this.mouseClickPosition.mouseX = t.touches ? t.touches[0].pageX : t.pageX, this.mouseClickPosition.mouseY = t.touches ? t.touches[0].pageY : t.pageY, this.mouseClickPosition.left = this.left, this.mouseClickPosition.right = this.right, this.mouseClickPosition.top = this.top, this.mouseClickPosition.bottom = this.bottom, this.parent && (this.bounds = this.calcDragLimits()), b(document.documentElement, p.move, this.move), b(document.documentElement, p.stop, this.handleUp); } }, calcDragLimits() { return { minLeft: this.left % this.grid[0], maxLeft: Math.floor((this.parentWidth - this.width - this.left) / this.grid[0]) * this.grid[0] + this.left, minRight: this.right % this.grid[0], maxRight: Math.floor((this.parentWidth - this.width - this.right) / this.grid[0]) * this.grid[0] + this.right, minTop: this.top % this.grid[1], maxTop: Math.floor((this.parentHeight - this.height - this.top) / this.grid[1]) * this.grid[1] + this.top, minBottom: this.bottom % this.grid[1], maxBottom: Math.floor((this.parentHeight - this.height - this.bottom) / this.grid[1]) * this.grid[1] + this.bottom }; }, deselect(t) { const e = t.target || t.srcElement, i = new RegExp(this.className + "-([trmbl]{2})", ""); !this.$el.contains(e) && !i.test(e.className) && (this.enabled && !this.preventDeactivation && (this.enabled = !1, this.$emit("deactivated"), this.$emit("update:active", !1)), f(document.documentElement, p.move, this.handleResize)), this.resetBoundsAndMouseState(); }, handleTouchDown(t, e) { p = y.touch, this.handleDown(t, e); }, handleDown(t, e) { e instanceof MouseEvent && e.which !== 1 || this.onResizeStart(t, e) !== !1 && (e.stopPropagation && e.stopPropagation(), this.lockAspectRatio && !t.includes("m") ? this.handle = "m" + t.substring(1) : this.handle = t, this.resizeEnable = !0, this.mouseClickPosition.mouseX = e.touches ? e.touches[0].pageX : e.pageX, this.mouseClickPosition.mouseY = e.touches ? e.touches[0].pageY : e.pageY, this.mouseClickPosition.left = this.left, this.mouseClickPosition.right = this.right, this.mouseClickPosition.top = this.top, this.mouseClickPosition.bottom = this.bottom, this.bounds = this.calcResizeLimits(), b(document.documentElement, p.move, this.handleResize), b(document.documentElement, p.stop, this.handleUp)); }, calcResizeLimits() { let t = this.minW, e = this.minH, i = this.maxW, s = this.maxH; const h = this.aspectFactor, [o, a] = this.grid, l = this.width, g = this.height, r = this.left, u = this.top, m = this.right, d = this.bottom; this.lockAspectRatio && (t / e > h ? e = t / h : t = h * e, i && s ? (i = Math.min(i, h * s), s = Math.min(s, i / h)) : i ? s = i / h : s && (i = h * s)), i = i - i % o, s = s - s % a; const n = { minLeft: null, maxLeft: null, minTop: null, maxTop: null, minRight: null, maxRight: null, minBottom: null, maxBottom: null }; return this.parent ? (n.minLeft = r % o, n.maxLeft = r + Math.floor((l - t) / o) * o, n.minTop = u % a, n.maxTop = u + Math.floor((g - e) / a) * a, n.minRight = m % o, n.maxRight = m + Math.floor((l - t) / o) * o, n.minBottom = d % a, n.maxBottom = d + Math.floor((g - e) / a) * a, i && (n.minLeft = Math.max(n.minLeft, this.parentWidth - m - i), n.minRight = Math.max(n.minRight, this.parentWidth - r - i)), s && (n.minTop = Math.max(n.minTop, this.parentHeight - d - s), n.minBottom = Math.max(n.minBottom, this.parentHeight - u - s)), this.lockAspectRatio && (n.minLeft = Math.max(n.minLeft, r - u * h), n.minTop = Math.max(n.minTop, u - r / h), n.minRight = Math.max(n.minRight, m - d * h), n.minBottom = Math.max(n.minBottom, d - m / h))) : (n.minLeft = null, n.maxLeft = r + Math.floor((l - t) / o) * o, n.minTop = null, n.maxTop = u + Math.floor((g - e) / a) * a, n.minRight = null, n.maxRight = m + Math.floor((l - t) / o) * o, n.minBottom = null, n.maxBottom = d + Math.floor((g - e) / a) * a, i && (n.minLeft = -(m + i), n.minRight = -(r + i)), s && (n.minTop = -(d + s), n.minBottom = -(u + s)), this.lockAspectRatio && i && s && (n.minLeft = Math.min(n.minLeft, -(m + i)), n.minTop = Math.min(n.minTop, -(s + d)), n.minRight = Math.min(n.minRight, -r - i), n.minBottom = Math.min(n.minBottom, -u - s))), n; }, move(t) { this.resizing ? this.handleResize(t) : this.dragEnable && this.handleDrag(t); }, handleDrag(t) { const e = this.axis, i = this.grid, s = this.bounds, h = this.mouseClickPosition, o = e && e !== "y" ? h.mouseX - (t.touches ? t.touches[0].pageX : t.pageX) : 0, a = e && e !== "x" ? h.mouseY - (t.touches ? t.touches[0].pageY : t.pageY) : 0, [l, g] = w(i, o, a, this.scale), r = c(h.left - l, s.minLeft, s.maxLeft), u = c(h.top - g, s.minTop, s.maxTop); if (this.onDrag(r, u) === !1) return; const m = c(h.right + l, s.minRight, s.maxRight), d = c(h.bottom + g, s.minBottom, s.maxBottom); this.left = r, this.top = u, this.right = m, this.bottom = d, this.$emit("dragging", this.left, this.top), this.dragging = !0; }, moveHorizontally(t) { const [e, i] = w(this.grid, t, this.top, 1), s = c(e, this.bounds.minLeft, this.bounds.maxLeft); this.left = s, this.right = this.parentWidth - this.width - s; }, moveVertically(t) { const [e, i] = w(this.grid, this.left, t, 1), s = c(i, this.bounds.minTop, this.bounds.maxTop); this.top = s, this.bottom = this.parentHeight - this.height - s; }, handleResize(t) { let e = this.left, i = this.top, s = this.right, h = this.bottom; const o = this.mouseClickPosition, a = this.aspectFactor, l = o.mouseX - (t.touches ? t.touches[0].pageX : t.pageX), g = o.mouseY - (t.touches ? t.touches[0].pageY : t.pageY); !this.widthTouched && l && (this.widthTouched = !0), !this.heightTouched && g && (this.heightTouched = !0); const [r, u] = w(this.grid, l, g, this.scale); this.handle.includes("b") ? (h = c( o.bottom + u, this.bounds.minBottom, this.bounds.maxBottom ), this.lockAspectRatio && this.resizingOnY && (s = this.right - (this.bottom - h) * a)) : this.handle.includes("t") && (i = c( o.top - u, this.bounds.minTop, this.bounds.maxTop ), this.lockAspectRatio && this.resizingOnY && (e = this.left - (this.top - i) * a)), this.handle.includes("r") ? (s = c( o.right + r, this.bounds.minRight, this.bounds.maxRight ), this.lockAspectRatio && this.resizingOnX && (h = this.bottom - (this.right - s) / a)) : this.handle.includes("l") && (e = c( o.left - r, this.bounds.minLeft, this.bounds.maxLeft ), this.lockAspectRatio && this.resizingOnX && (i = this.top - (this.left - e) / a)); const m = R(this.parentWidth, e, s), d = S(this.parentHeight, i, h); this.onResize(this.handle, e, i, m, d) !== !1 && (this.left = e, this.top = i, this.right = s, this.bottom = h, this.width = m, this.height = d, this.$emit("resizing", this.left, this.top, this.width, this.height), this.resizing = !0); }, changeWidth(t) { const [e, i] = w(this.grid, t, 0, 1), s = c( this.parentWidth - e - this.left, this.bounds.minRight, this.bounds.maxRight ); let h = this.bottom; this.lockAspectRatio && (h = this.bottom - (this.right - s) / this.aspectFactor); const o = R(this.parentWidth, this.left, s), a = S(this.parentHeight, this.top, h); this.right = s, this.bottom = h, this.width = o, this.height = a; }, changeHeight(t) { const [e, i] = w(this.grid, 0, t, 1), s = c( this.parentHeight - i - this.top, this.bounds.minBottom, this.bounds.maxBottom ); let h = this.right; this.lockAspectRatio && (h = this.right - (this.bottom - s) * this.aspectFactor); const o = R(this.parentWidth, this.left, h), a = S(this.parentHeight, this.top, s); this.right = h, this.bottom = s, this.width = o, this.height = a; }, handleUp(t) { this.handle = null, this.resetBoundsAndMouseState(), this.dragEnable = !1, this.resizeEnable = !1, this.resizing && (this.resizing = !1, this.$emit("resizeStop", this.left, this.top, this.width, this.height)), this.dragging && (this.dragging = !1, this.$emit("dragStop", this.left, this.top)), f(document.documentElement, p.move, this.handleResize); } }, computed: { style() { return { transform: `translate(${this.left}px, ${this.top}px)`, width: this.computedWidth, height: this.computedHeight, zIndex: this.zIndex, ...this.dragging && this.disableUserSelect ? C : X }; }, actualHandles() { return this.resizable ? this.handles : []; }, computedWidth() { return this.w === "auto" && !this.widthTouched ? "auto" : this.width + "px"; }, computedHeight() { return this.h === "auto" && !this.heightTouched ? "auto" : this.height + "px"; }, minW() { return this.minWidth; }, minH() { return this.minHeight; }, maxW() { return this.maxWidth; }, maxH() { return this.maxHeight; }, resizingOnX() { return !!this.handle && (this.handle.includes("l") || this.handle.includes("r")); }, resizingOnY() { return !!this.handle && (this.handle.includes("t") || this.handle.includes("b")); }, isCornerHandle() { return !!this.handle && ["tl", "tr", "br", "bl"].includes(this.handle); } }, watch: { active(t) { this.enabled = t, t ? this.$emit("activated") : this.$emit("deactivated"); }, z(t) { (t >= 0 || t === "auto") && (this.zIndex = t); }, x(t) { this.resizing || this.dragging || (this.parent && (this.bounds = this.calcDragLimits()), this.moveHorizontally(t)); }, y(t) { this.resizing || this.dragging || (this.parent && (this.bounds = this.calcDragLimits()), this.moveVertically(t)); }, lockAspectRatio(t) { t ? this.aspectFactor = this.width / this.height : this.aspectFactor = void 0; }, w(t) { this.resizing || this.dragging || (this.parent && (this.bounds = this.calcResizeLimits()), this.changeWidth(t)); }, h(t) { this.resizing || this.dragging || (this.parent && (this.bounds = this.calcResizeLimits()), this.changeHeight(t)); } } }, A = ["onMousedown", "onTouchstart"]; function F(t, e, i, s, h, o) { return z(), v("div", { style: H(o.style), class: T([{ [i.classNameActive]: t.enabled, [i.classNameDragging]: t.dragging, [i.classNameResizing]: t.resizing, [i.classNameDraggable]: i.draggable, [i.classNameResizable]: i.resizable }, i.className]), onMousedown: e[0] || (e[0] = (...a) => o.elementMouseDown && o.elementMouseDown(...a)), onTouchstart: e[1] || (e[1] = (...a) => o.elementTouchDown && o.elementTouchDown(...a)) }, [ (z(!0), v(E, null, L(o.actualHandles, (a) => (z(), v("div", { key: a, class: T([i.classNameHandle, i.classNameHandle + "-" + a]), style: H({ display: t.enabled ? "block" : "none" }), onMousedown: B((l) => o.handleDown(a, l), ["stop", "prevent"]), onTouchstart: B((l) => o.handleTouchDown(a, l), ["stop", "prevent"]) }, [ k(t.$slots, a) ], 46, A))), 128)), k(t.$slots, "default") ], 38); } const U = /* @__PURE__ */ P(Y, [["render", F]]); function M(t) { M.installed || (M.installed = !0, t.component("VueDraggableResizable", U)); } const V = { install: M }; let x = null; typeof window < "u" ? x = window.Vue : typeof global < "u" && (x = global.Vue); x && x.use(V); export { U as default, M as install };