Commit 6c03aa91 authored by kaitly205422@163.com's avatar kaitly205422@163.com

替换房间拖拽组件

parent 7dec2a96
import { isFunction } from './fns'
export function matchesSelectorToParentElements (el, selector, baseNode) {
let node = el
const matchesSelectorFunc = [
'matches',
'webkitMatchesSelector',
'mozMatchesSelector',
'msMatchesSelector',
'oMatchesSelector'
].find(func => isFunction(node[func]))
if (!isFunction(node[matchesSelectorFunc])) return false
do {
if (node[matchesSelectorFunc](selector)) return true
if (node === baseNode) return false
node = node.parentNode
} while (node)
return false
}
export function getComputedSize ($el) {
const style = window.getComputedStyle($el)
return [
parseFloat(style.getPropertyValue('width'), 10),
parseFloat(style.getPropertyValue('height'), 10)
]
}
export function addEvent (el, event, handler) {
if (!el) {
return
}
if (el.attachEvent) {
el.attachEvent('on' + event, handler)
} else if (el.addEventListener) {
el.addEventListener(event, handler, true)
} else {
el['on' + event] = handler
}
}
export function removeEvent (el, event, handler) {
if (!el) {
return
}
if (el.detachEvent) {
el.detachEvent('on' + event, handler)
} else if (el.removeEventListener) {
el.removeEventListener(event, handler, true)
} else {
el['on' + event] = null
}
}
export function isFunction (func) {
return (typeof func === 'function' || Object.prototype.toString.call(func) === '[object Function]')
}
export function snapToGrid (grid, pendingX, pendingY, scale = 1) {
const [scaleX, scaleY] = typeof scale === 'number' ? [scale, scale] : scale
const x = Math.round((pendingX / scaleX) / grid[0]) * grid[0]
const y = Math.round((pendingY / scaleY) / grid[1]) * grid[1]
return [x, y]
}
export function getSize (el) {
const rect = el.getBoundingClientRect()
return [
parseInt(rect.width),
parseInt(rect.height)
]
}
export function computeWidth (parentWidth, left, right) {
return parentWidth - left - right
}
export function computeHeight (parentHeight, top, bottom) {
return parentHeight - top - bottom
}
export function restrictToBounds (value, min, max) {
if (min !== null && value < min) {
return min
}
if (max !== null && max < value) {
return max
}
return value
}
.vdr {
touch-action: none;
position: absolute;
box-sizing: border-box;
border: 1px dashed black;
}
.handle {
box-sizing: border-box;
position: absolute;
width: 10px;
height: 10px;
background: #EEE;
border: 1px solid #333;
}
.handle-tl {
top: -10px;
left: -10px;
cursor: nw-resize;
}
.handle-tm {
top: -10px;
left: 50%;
margin-left: -5px;
cursor: n-resize;
}
.handle-tr {
top: -10px;
right: -10px;
cursor: ne-resize;
}
.handle-ml {
top: 50%;
margin-top: -5px;
left: -10px;
cursor: w-resize;
}
.handle-mr {
top: 50%;
margin-top: -5px;
right: -10px;
cursor: e-resize;
}
.handle-bl {
bottom: -10px;
left: -10px;
cursor: sw-resize;
}
.handle-bm {
bottom: -10px;
left: 50%;
margin-left: -5px;
cursor: s-resize;
}
.handle-br {
bottom: -10px;
right: -10px;
cursor: se-resize;
}
@media only screen and (max-width: 768px) {
[class*="handle-"]:before {
content: '';
left: -10px;
right: -10px;
bottom: -10px;
top: -10px;
position: absolute;
}
}
<template>
<div
:style="style"
:class="[
{
[classNameActive]: enabled,
[classNameDragging]: dragging,
[classNameResizing]: resizing,
[classNameDraggable]: draggable,
[classNameResizable]: resizable,
},
className,
]"
@mousedown="elementMouseDown"
@touchstart="elementTouchDown"
>
<div
v-for="handle in actualHandles"
:key="handle"
:class="[classNameHandle, classNameHandle + '-' + handle]"
:style="{ display: enabled ? 'block' : 'none' }"
@mousedown.stop.prevent="handleDown(handle, $event)"
@touchstart.stop.prevent="handleTouchDown(handle, $event)"
>
<slot :name="handle"></slot>
</div>
<slot></slot>
</div>
</template>
<script>
import {
matchesSelectorToParentElements,
getComputedSize,
addEvent,
removeEvent,
} from "./utils/dom";
import {
computeWidth,
computeHeight,
restrictToBounds,
snapToGrid,
} from "./utils/fns";
const events = {
mouse: {
start: "mousedown",
move: "mousemove",
stop: "mouseup",
},
touch: {
start: "touchstart",
move: "touchmove",
stop: "touchend",
},
};
const userSelectNone = {
userSelect: "none",
MozUserSelect: "none",
WebkitUserSelect: "none",
MsUserSelect: "none",
};
const userSelectAuto = {
userSelect: "auto",
MozUserSelect: "auto",
WebkitUserSelect: "auto",
MsUserSelect: "auto",
};
let eventsFor = events.mouse;
export default {
replace: true,
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: true,
},
enableNativeDrag: {
type: Boolean,
default: false,
},
preventDeactivation: {
type: Boolean,
default: false,
},
active: {
type: Boolean,
default: false,
},
draggable: {
type: Boolean,
default: true,
},
resizable: {
type: Boolean,
default: true,
},
lockAspectRatio: {
type: Boolean,
default: false,
},
w: {
type: [Number, String],
default: 200,
validator: (val) => {
if (typeof val === "number") {
return val > 0;
}
return val === "auto";
},
},
h: {
type: [Number, String],
default: 200,
validator: (val) => {
if (typeof val === "number") {
return val > 0;
}
return val === "auto";
},
},
minWidth: {
type: Number,
default: 0,
validator: (val) => val >= 0,
},
minHeight: {
type: Number,
default: 0,
validator: (val) => val >= 0,
},
maxWidth: {
type: Number,
default: null,
validator: (val) => val >= 0,
},
maxHeight: {
type: Number,
default: null,
validator: (val) => val >= 0,
},
x: {
type: Number,
default: 0,
},
y: {
type: Number,
default: 0,
},
z: {
type: [String, Number],
default: "auto",
validator: (val) => (typeof val === "string" ? val === "auto" : val >= 0),
},
handles: {
type: Array,
default: () => ["tl", "tm", "tr", "mr", "br", "bm", "bl", "ml"],
validator: (val) => {
const s = new Set(["tl", "tm", "tr", "mr", "br", "bm", "bl", "ml"]);
return new Set(val.filter((h) => s.has(h))).size === val.length;
},
},
dragHandle: {
type: String,
default: null,
},
dragCancel: {
type: String,
default: null,
},
axis: {
type: String,
default: "both",
validator: (val) => ["x", "y", "both"].includes(val),
},
grid: {
type: Array,
default: () => [1, 1],
},
parent: {
type: Boolean,
default: false,
},
scale: {
type: [Number, Array],
default: 1,
validator: (val) => {
if (typeof val === "number") {
return val > 0;
}
return val.length === 2 && val[0] > 0 && val[1] > 0;
},
},
onDragStart: {
type: Function,
default: () => true,
},
onDrag: {
type: Function,
default: () => true,
},
onResizeStart: {
type: Function,
default: () => true,
},
onResize: {
type: Function,
default: () => true,
},
},
data: function () {
return {
left: this.x,
top: this.y,
right: null,
bottom: null,
width: null,
height: null,
widthTouched: false,
heightTouched: false,
aspectFactor: null,
parentWidth: null,
parentHeight: null,
minW: this.minWidth,
minH: this.minHeight,
maxW: this.maxWidth,
maxH: this.maxHeight,
handle: null,
enabled: this.active,
resizing: false,
dragging: false,
dragEnable: false,
resizeEnable: false,
zIndex: this.z,
};
},
created: function () {
// eslint-disable-next-line
if (this.maxWidth && this.minWidth > this.maxWidth)
console.warn(
"[Vdr warn]: Invalid prop: minWidth cannot be greater than maxWidth"
);
// eslint-disable-next-line
if (this.maxWidth && this.minHeight > this.maxHeight)
console.warn(
"[Vdr warn]: Invalid prop: minHeight cannot be greater than maxHeight"
);
this.resetBoundsAndMouseState();
},
mounted: function () {
if (!this.enableNativeDrag) {
this.$el.ondragstart = () => false;
}
const [parentWidth, parentHeight] = this.getParentSize();
this.parentWidth = parentWidth;
this.parentHeight = parentHeight;
const [width, height] = getComputedSize(this.$el);
this.aspectFactor =
(this.w !== "auto" ? this.w : width) /
(this.h !== "auto" ? this.h : height);
this.width = this.w !== "auto" ? this.w : width;
this.height = this.h !== "auto" ? this.h : height;
this.right = this.parentWidth - this.width - this.left;
this.bottom = this.parentHeight - this.height - this.top;
if (this.active) {
this.$emit("activated");
}
addEvent(document.documentElement, "mousedown", this.deselect);
addEvent(document.documentElement, "touchend touchcancel", this.deselect);
addEvent(window, "resize", this.checkParentSize);
},
beforeDestroy: function () {
removeEvent(document.documentElement, "mousedown", this.deselect);
removeEvent(document.documentElement, "touchstart", this.handleUp);
removeEvent(document.documentElement, "mousemove", this.move);
removeEvent(document.documentElement, "touchmove", this.move);
removeEvent(document.documentElement, "mouseup", this.handleUp);
removeEvent(
document.documentElement,
"touchend touchcancel",
this.deselect
);
removeEvent(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 [newParentWidth, newParentHeight] = this.getParentSize();
this.parentWidth = newParentWidth;
this.parentHeight = newParentHeight;
this.right = this.parentWidth - this.width - this.left;
this.bottom = this.parentHeight - this.height - this.top;
}
},
getParentSize() {
if (this.parent) {
const style = window.getComputedStyle(this.$el.parentNode, null);
return [parseInt(style.getPropertyValue("width"), 10), 10000];
}
return [null, null];
},
elementTouchDown(e) {
eventsFor = events.touch;
this.elementDown(e);
},
elementMouseDown(e) {
eventsFor = events.mouse;
this.elementDown(e);
},
elementDown(e) {
if (e instanceof MouseEvent && e.which !== 1) {
return;
}
const target = e.target || e.srcElement;
if (this.$el.contains(target)) {
if (this.onDragStart(e) === false) {
return;
}
if (
(this.dragHandle &&
!matchesSelectorToParentElements(
target,
this.dragHandle,
this.$el
)) ||
(this.dragCancel &&
matchesSelectorToParentElements(target, this.dragCancel, this.$el))
) {
this.dragging = false;
return;
}
if (!this.enabled) {
this.enabled = true;
this.$emit("activated");
this.$emit("update:active", true);
}
if (this.draggable) {
this.dragEnable = true;
}
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;
if (this.parent) {
this.bounds = this.calcDragLimits();
}
addEvent(document.documentElement, eventsFor.move, this.move);
addEvent(document.documentElement, eventsFor.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(e) {
const target = e.target || e.srcElement;
const regex = new RegExp(this.className + "-([trmbl]{2})", "");
if (!this.$el.contains(target) && !regex.test(target.className)) {
if (this.enabled && !this.preventDeactivation) {
this.enabled = false;
this.$emit("deactivated");
this.$emit("update:active", false);
}
removeEvent(
document.documentElement,
eventsFor.move,
this.handleResize
);
}
this.resetBoundsAndMouseState();
},
handleTouchDown(handle, e) {
eventsFor = events.touch;
this.handleDown(handle, e);
},
handleDown(handle, e) {
if (e instanceof MouseEvent && e.which !== 1) {
return;
}
if (this.onResizeStart(handle, e) === false) {
return;
}
if (e.stopPropagation) e.stopPropagation();
// Here we avoid a dangerous recursion by faking
// corner handles as middle handles
if (this.lockAspectRatio && !handle.includes("m")) {
this.handle = "m" + handle.substring(1);
} else {
this.handle = handle;
}
this.resizeEnable = true;
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();
addEvent(document.documentElement, eventsFor.move, this.handleResize);
addEvent(document.documentElement, eventsFor.stop, this.handleUp);
},
calcResizeLimits() {
let minW = this.minW;
let minH = this.minH;
let maxW = this.maxW;
let maxH = this.maxH;
const aspectFactor = this.aspectFactor;
const [gridX, gridY] = this.grid;
const width = this.width;
const height = this.height;
const left = this.left;
const top = this.top;
const right = this.right;
const bottom = this.bottom;
if (this.lockAspectRatio) {
if (minW / minH > aspectFactor) {
minH = minW / aspectFactor;
} else {
minW = aspectFactor * minH;
}
if (maxW && maxH) {
maxW = Math.min(maxW, aspectFactor * maxH);
maxH = Math.min(maxH, maxW / aspectFactor);
} else if (maxW) {
maxH = maxW / aspectFactor;
} else if (maxH) {
maxW = aspectFactor * maxH;
}
}
maxW = maxW - (maxW % gridX);
maxH = maxH - (maxH % gridY);
const limits = {
minLeft: null,
maxLeft: null,
minTop: null,
maxTop: null,
minRight: null,
maxRight: null,
minBottom: null,
maxBottom: null,
};
if (this.parent) {
limits.minLeft = left % gridX;
limits.maxLeft = left + Math.floor((width - minW) / gridX) * gridX;
limits.minTop = top % gridY;
limits.maxTop = top + Math.floor((height - minH) / gridY) * gridY;
limits.minRight = right % gridX;
limits.maxRight = right + Math.floor((width - minW) / gridX) * gridX;
limits.minBottom = bottom % gridY;
limits.maxBottom = bottom + Math.floor((height - minH) / gridY) * gridY;
if (maxW) {
limits.minLeft = Math.max(
limits.minLeft,
this.parentWidth - right - maxW
);
limits.minRight = Math.max(
limits.minRight,
this.parentWidth - left - maxW
);
}
if (maxH) {
limits.minTop = Math.max(
limits.minTop,
this.parentHeight - bottom - maxH
);
limits.minBottom = Math.max(
limits.minBottom,
this.parentHeight - top - maxH
);
}
if (this.lockAspectRatio) {
limits.minLeft = Math.max(limits.minLeft, left - top * aspectFactor);
limits.minTop = Math.max(limits.minTop, top - left / aspectFactor);
limits.minRight = Math.max(
limits.minRight,
right - bottom * aspectFactor
);
limits.minBottom = Math.max(
limits.minBottom,
bottom - right / aspectFactor
);
}
} else {
limits.minLeft = null;
limits.maxLeft = left + Math.floor((width - minW) / gridX) * gridX;
limits.minTop = null;
limits.maxTop = top + Math.floor((height - minH) / gridY) * gridY;
limits.minRight = null;
limits.maxRight = right + Math.floor((width - minW) / gridX) * gridX;
limits.minBottom = null;
limits.maxBottom = bottom + Math.floor((height - minH) / gridY) * gridY;
if (maxW) {
limits.minLeft = -(right + maxW);
limits.minRight = -(left + maxW);
}
if (maxH) {
limits.minTop = -(bottom + maxH);
limits.minBottom = -(top + maxH);
}
if (this.lockAspectRatio && maxW && maxH) {
limits.minLeft = Math.min(limits.minLeft, -(right + maxW));
limits.minTop = Math.min(limits.minTop, -(maxH + bottom));
limits.minRight = Math.min(limits.minRight, -left - maxW);
limits.minBottom = Math.min(limits.minBottom, -top - maxH);
}
}
return limits;
},
move(e) {
if (this.resizing) {
this.handleResize(e);
} else if (this.dragEnable) {
this.handleDrag(e);
}
},
handleDrag(e) {
const axis = this.axis;
const grid = this.grid;
const bounds = this.bounds;
const mouseClickPosition = this.mouseClickPosition;
const tmpDeltaX =
axis && axis !== "y"
? mouseClickPosition.mouseX -
(e.touches ? e.touches[0].pageX : e.pageX)
: 0;
const tmpDeltaY =
axis && axis !== "x"
? mouseClickPosition.mouseY -
(e.touches ? e.touches[0].pageY : e.pageY)
: 0;
const [deltaX, deltaY] = snapToGrid(
grid,
tmpDeltaX,
tmpDeltaY,
this.scale
);
const left = restrictToBounds(
mouseClickPosition.left - deltaX,
bounds.minLeft,
bounds.maxLeft
);
const top = restrictToBounds(
mouseClickPosition.top - deltaY,
bounds.minTop,
bounds.maxTop
);
if (this.onDrag(left, top) === false) {
return;
}
const right = restrictToBounds(
mouseClickPosition.right + deltaX,
bounds.minRight,
bounds.maxRight
);
const bottom = restrictToBounds(
mouseClickPosition.bottom + deltaY,
bounds.minBottom,
bounds.maxBottom
);
this.left = left;
this.top = top;
this.right = right;
this.bottom = bottom;
this.$emit("dragging", this.left, this.top);
this.dragging = true;
},
moveHorizontally(val) {
// should calculate with scale 1.
const [deltaX, _] = snapToGrid(this.grid, val, this.top, 1);
const left = restrictToBounds(
deltaX,
this.bounds.minLeft,
this.bounds.maxLeft
);
this.left = left;
this.right = this.parentWidth - this.width - left;
},
moveVertically(val) {
// should calculate with scale 1.
const [_, deltaY] = snapToGrid(this.grid, this.left, val, 1);
const top = restrictToBounds(
deltaY,
this.bounds.minTop,
this.bounds.maxTop
);
this.top = top;
this.bottom = this.parentHeight - this.height - top;
},
handleResize(e) {
let left = this.left;
let top = this.top;
let right = this.right;
let bottom = this.bottom;
const mouseClickPosition = this.mouseClickPosition;
const lockAspectRatio = this.lockAspectRatio;
const aspectFactor = this.aspectFactor;
const tmpDeltaX =
mouseClickPosition.mouseX - (e.touches ? e.touches[0].pageX : e.pageX);
const tmpDeltaY =
mouseClickPosition.mouseY - (e.touches ? e.touches[0].pageY : e.pageY);
if (!this.widthTouched && tmpDeltaX) {
this.widthTouched = true;
}
if (!this.heightTouched && tmpDeltaY) {
this.heightTouched = true;
}
const [deltaX, deltaY] = snapToGrid(
this.grid,
tmpDeltaX,
tmpDeltaY,
this.scale
);
if (this.handle.includes("b")) {
bottom = restrictToBounds(
mouseClickPosition.bottom + deltaY,
this.bounds.minBottom,
this.bounds.maxBottom
);
if (this.lockAspectRatio && this.resizingOnY) {
right = this.right - (this.bottom - bottom) * aspectFactor;
}
} else if (this.handle.includes("t")) {
top = restrictToBounds(
mouseClickPosition.top - deltaY,
this.bounds.minTop,
this.bounds.maxTop
);
if (this.lockAspectRatio && this.resizingOnY) {
left = this.left - (this.top - top) * aspectFactor;
}
}
if (this.handle.includes("r")) {
right = restrictToBounds(
mouseClickPosition.right + deltaX,
this.bounds.minRight,
this.bounds.maxRight
);
if (this.lockAspectRatio && this.resizingOnX) {
bottom = this.bottom - (this.right - right) / aspectFactor;
}
} else if (this.handle.includes("l")) {
left = restrictToBounds(
mouseClickPosition.left - deltaX,
this.bounds.minLeft,
this.bounds.maxLeft
);
if (this.lockAspectRatio && this.resizingOnX) {
top = this.top - (this.left - left) / aspectFactor;
}
}
const width = computeWidth(this.parentWidth, left, right);
const height = computeHeight(this.parentHeight, top, bottom);
if (this.onResize(this.handle, left, top, width, height) === false) {
return;
}
this.left = left;
this.top = top;
this.right = right;
this.bottom = bottom;
this.width = width;
this.height = height;
this.$emit("resizing", this.left, this.top, this.width, this.height);
this.resizing = true;
},
changeWidth(val) {
// should calculate with scale 1.
const [newWidth, _] = snapToGrid(this.grid, val, 0, 1);
let right = restrictToBounds(
this.parentWidth - newWidth - this.left,
this.bounds.minRight,
this.bounds.maxRight
);
let bottom = this.bottom;
if (this.lockAspectRatio) {
bottom = this.bottom - (this.right - right) / this.aspectFactor;
}
const width = computeWidth(this.parentWidth, this.left, right);
const height = computeHeight(this.parentHeight, this.top, bottom);
this.right = right;
this.bottom = bottom;
this.width = width;
this.height = height;
},
changeHeight(val) {
// should calculate with scale 1.
const [_, newHeight] = snapToGrid(this.grid, 0, val, 1);
let bottom = restrictToBounds(
this.parentHeight - newHeight - this.top,
this.bounds.minBottom,
this.bounds.maxBottom
);
let right = this.right;
if (this.lockAspectRatio) {
right = this.right - (this.bottom - bottom) * this.aspectFactor;
}
const width = computeWidth(this.parentWidth, this.left, right);
const height = computeHeight(this.parentHeight, this.top, bottom);
this.right = right;
this.bottom = bottom;
this.width = width;
this.height = height;
},
handleUp(e) {
this.handle = null;
this.resetBoundsAndMouseState();
this.dragEnable = false;
this.resizeEnable = false;
if (this.resizing) {
this.resizing = false;
this.$emit("resizestop", this.left, this.top, this.width, this.height);
}
if (this.dragging) {
this.dragging = false;
this.$emit("dragstop", this.left, this.top);
}
removeEvent(document.documentElement, eventsFor.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
? userSelectNone
: userSelectAuto),
};
},
actualHandles() {
if (!this.resizable) return [];
return this.handles;
},
computedWidth() {
if (this.w === "auto") {
if (!this.widthTouched) {
return "auto";
}
}
return this.width + "px";
},
computedHeight() {
if (this.h === "auto") {
if (!this.heightTouched) {
return "auto";
}
}
return this.height + "px";
},
resizingOnX() {
return (
Boolean(this.handle) &&
(this.handle.includes("l") || this.handle.includes("r"))
);
},
resizingOnY() {
return (
Boolean(this.handle) &&
(this.handle.includes("t") || this.handle.includes("b"))
);
},
isCornerHandle() {
return (
Boolean(this.handle) && ["tl", "tr", "br", "bl"].includes(this.handle)
);
},
},
watch: {
active(val) {
this.enabled = val;
if (val) {
this.$emit("activated");
} else {
this.$emit("deactivated");
}
},
z(val) {
if (val >= 0 || val === "auto") {
this.zIndex = val;
}
},
x(val) {
if (this.resizing || this.dragging) {
return;
}
if (this.parent) {
this.bounds = this.calcDragLimits();
}
this.moveHorizontally(val);
},
y(val) {
if (this.resizing || this.dragging) {
return;
}
if (this.parent) {
this.bounds = this.calcDragLimits();
}
this.moveVertically(val);
},
lockAspectRatio(val) {
if (val) {
this.aspectFactor = this.width / this.height;
} else {
this.aspectFactor = undefined;
}
},
minWidth(val) {
if (val > 0 && val <= this.width) {
this.minW = val;
}
},
minHeight(val) {
if (val > 0 && val <= this.height) {
this.minH = val;
}
},
maxWidth(val) {
this.maxW = val;
},
maxHeight(val) {
this.maxH = val;
},
w(val) {
if (this.resizing || this.dragging) {
return;
}
if (this.parent) {
this.bounds = this.calcResizeLimits();
}
this.changeWidth(val);
},
h(val) {
if (this.resizing || this.dragging) {
return;
}
if (this.parent) {
this.bounds = this.calcResizeLimits();
}
this.changeHeight(val);
},
},
};
</script>
...@@ -5,12 +5,12 @@ export function debounce(fn, delay) { ...@@ -5,12 +5,12 @@ export function debounce(fn, delay) {
// 记录上一次的延时器 // 记录上一次的延时器
var timer = null; var timer = null;
var delay = delay || 200; var delay = delay || 200;
return function() { return function () {
var args = arguments; var args = arguments;
var that = this; var that = this;
// 清除上一次延时器 // 清除上一次延时器
clearTimeout(timer); clearTimeout(timer);
timer = setTimeout(function() { timer = setTimeout(function () {
fn.apply(that, args); fn.apply(that, args);
}, delay); }, delay);
}; };
...@@ -38,7 +38,7 @@ export const rotateBase64Img = (src, edg, callback) => { ...@@ -38,7 +38,7 @@ export const rotateBase64Img = (src, edg, callback) => {
image.src = src; image.src = src;
image.crossOrigin = "anonymous"; image.crossOrigin = "anonymous";
image.onload = function() { image.onload = function () {
imgW = image.width; imgW = image.width;
imgH = image.height; imgH = image.height;
size = imgW > imgH ? imgW : imgH; size = imgW > imgH ? imgW : imgH;
......
...@@ -23,8 +23,10 @@ ...@@ -23,8 +23,10 @@
<!-- @click.native="changeName(item)" --> <!-- @click.native="changeName(item)" -->
<!-- :static="item.static" --> <!-- :static="item.static" -->
<div :style="{ height: layoutHeight + 'px' }"> <div :style="{ minHeight: layoutHeight + 'px' }">
<vue-draggable-resizable <vue-draggable-resizable
parent
ref="dragResizable"
v-for="item in layout" v-for="item in layout"
:x="(W / 12) * item.x" :x="(W / 12) * item.x"
:y="item.y * 30" :y="item.y * 30"
...@@ -42,6 +44,7 @@ ...@@ -42,6 +44,7 @@
movedEvent(item, x, y); movedEvent(item, x, y);
} }
" "
@resizing="(x, y, w, h) => onResize(item, x, y, w, h)"
@activated="onActivated(item)" @activated="onActivated(item)"
@click.native="dbClickEvent($event, item)" @click.native="dbClickEvent($event, item)"
:style="{ :style="{
...@@ -198,9 +201,10 @@ import screenfull from "screenfull"; ...@@ -198,9 +201,10 @@ import screenfull from "screenfull";
import { Toast, Dialog } from "vant"; import { Toast, Dialog } from "vant";
import { debounce } from "@/utils/common.js"; import { debounce } from "@/utils/common.js";
import { getFun, postFun } from "@/service/table.js"; import { getFun, postFun } from "@/service/table.js";
import VueDraggableResizable from "vue-draggable-resizable"; import VueDraggableResizable from "@/components/vue-draggable-resizable/vue-draggable-resizable.vue";
import "vue-draggable-resizable/dist/VueDraggableResizable.css"; import "@/components/vue-draggable-resizable/vue-draggable-resizable.css";
// 动态添加/删除 // 动态添加/删除
var timer;
export default { export default {
name: "riskView", name: "riskView",
components: { components: {
...@@ -511,6 +515,7 @@ export default { ...@@ -511,6 +515,7 @@ export default {
const index = this.layout.map((item) => item.i).indexOf(val); const index = this.layout.map((item) => item.i).indexOf(val);
this.layout.splice(index, 1); this.layout.splice(index, 1);
this.layoutData.splice(index, 1); this.layoutData.splice(index, 1);
this.updateLayoutHeight();
// postFun("/ledger/room/delete/" + val) // postFun("/ledger/room/delete/" + val)
// .then(res => { // .then(res => {
// if (res.code == 200) { // if (res.code == 200) {
...@@ -551,6 +556,7 @@ export default { ...@@ -551,6 +556,7 @@ export default {
this.isBase = true; this.isBase = true;
this.show = true; this.show = true;
}, },
// 更新画布高度
updateLayoutHeight() { updateLayoutHeight() {
const max = Math.max( const max = Math.max(
...this.layoutData.map((x) => { ...this.layoutData.map((x) => {
...@@ -576,7 +582,7 @@ export default { ...@@ -576,7 +582,7 @@ export default {
// 拖动时判断layoutHeight是否需要更新 // 拖动时判断layoutHeight是否需要更新
item.x = (x / this.W) * 12; item.x = (x / this.W) * 12;
item.y = y / 30; item.y = y / 30;
this.updateLayoutHeight(); debounce(this.updateLayoutHeight)();
// if (top > this.layoutHeight) { // if (top > this.layoutHeight) {
// this.layoutHeight = top; // this.layoutHeight = top;
// } // }
...@@ -587,6 +593,9 @@ export default { ...@@ -587,6 +593,9 @@ export default {
item.w = (w / this.W) * 12; item.w = (w / this.W) * 12;
item.h = h / 30; item.h = h / 30;
}, },
onResize() {
debounce(this.updateLayoutHeight)();
},
// 激活 // 激活
onActivated(item) { onActivated(item) {
if (this.beforItem) { if (this.beforItem) {
...@@ -720,6 +729,7 @@ export default { ...@@ -720,6 +729,7 @@ export default {
y: this.layout.length + (this.colNum / 2 || 12), y: this.layout.length + (this.colNum / 2 || 12),
w: 2, w: 2,
h: 3, h: 3,
zIndex: 10,
i: this.copyRoom.isCopy ? this.copyRoom.id : i, i: this.copyRoom.isCopy ? this.copyRoom.id : i,
id: this.copyRoom.isCopy ? this.copyRoom.id : i, id: this.copyRoom.isCopy ? this.copyRoom.id : i,
name: this.roomName, name: this.roomName,
...@@ -732,6 +742,7 @@ export default { ...@@ -732,6 +742,7 @@ export default {
isDraggable: true, isDraggable: true,
isResizable: true, isResizable: true,
}; };
this.beforItem = this.layOutItem;
this.layout.push(this.layOutItem); this.layout.push(this.layOutItem);
let data = { let data = {
...@@ -750,6 +761,7 @@ export default { ...@@ -750,6 +761,7 @@ export default {
this.layoutData.push(data); this.layoutData.push(data);
this.resetCopy(); this.resetCopy();
this.updateLayoutHeight();
// postFun("/ledger/room/save", data) // postFun("/ledger/room/save", data)
// .then(res => { // .then(res => {
// if (res.code == 200) { // if (res.code == 200) {
...@@ -946,6 +958,7 @@ export default { ...@@ -946,6 +958,7 @@ export default {
.rowText { .rowText {
writing-mode: vertical-rl; writing-mode: vertical-rl;
-webkit-writing-mode: vertical-rl; -webkit-writing-mode: vertical-rl;
font-size: 18px;
} }
.vue-grid-item .no-drag { .vue-grid-item .no-drag {
height: 100%; height: 100%;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment