<template>
|
<div :style="style" :class="{draggable: draggable, resizable: resizable, active: enabled, dragging: dragging, resizing: resizing}" class="vdr" @mousedown="elmDown" @touchstart.stop="elmDown" @dblclick="fillParent" @keydown.stop.prevent="handleKeyDown">
|
<template v-for="handle in handles">
|
<div v-if="resizable" :key="handle" :class="'handle-' + handle" :style="{ display: enabled ? 'block' : 'none'}" class="handle" @mousedown.stop.prevent="handleDown(handle, $event)" @touchstart.stop.prevent="handleDown(handle, $event)"></div>
|
</template>
|
<slot></slot>
|
</div>
|
</template>
|
|
<script>
|
import { matchesSelectorToParentElements } from "../utils/dom"; // 将选择器与父元素匹配
|
|
export default {
|
replace: true,
|
name: "VueDraggableResizable",
|
props: {
|
active: {
|
type: Boolean,
|
default: false
|
},
|
draggable: {
|
type: Boolean,
|
default: true
|
},
|
resizable: {
|
type: Boolean,
|
default: true
|
},
|
w: {
|
type: Number,
|
default: 200,
|
validator: function(val) {
|
return val > 0;
|
}
|
},
|
h: {
|
type: Number,
|
default: 200,
|
validator: function(val) {
|
return val > 0;
|
}
|
},
|
minw: {
|
type: Number,
|
default: 50,
|
validator: function(val) {
|
return val >= 0;
|
}
|
},
|
minh: {
|
type: Number,
|
default: 50,
|
validator: function(val) {
|
return val >= 0;
|
}
|
},
|
x: {
|
type: Number,
|
default: 0,
|
validator: function(val) {
|
return typeof val === "number";
|
}
|
},
|
y: {
|
type: Number,
|
default: 0,
|
validator: function(val) {
|
return typeof val === "number";
|
}
|
},
|
z: {
|
type: [String, Number],
|
default: "auto",
|
validator: function(val) {
|
const valid = typeof val === "string" ? val === "auto" : val >= 0;
|
return valid;
|
}
|
},
|
handles: {
|
type: Array,
|
default: function() {
|
return ["tl", "tm", "tr", "mr", "br", "bm", "bl", "ml"];
|
},
|
validator: function(val) {
|
var 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: function(val) {
|
return ["x", "y", "both"].indexOf(val) !== -1;
|
}
|
},
|
grid: {
|
type: Array,
|
default: function() {
|
return [1, 1];
|
}
|
},
|
parent: {
|
type: Boolean,
|
default: false
|
},
|
maximize: {
|
type: Boolean,
|
default: false
|
},
|
// 定义组件是否开启冲突检测
|
isConflictCheck: {
|
type: Boolean,
|
default: false
|
},
|
// 是否开启元素对齐
|
snap: {
|
type: Boolean,
|
default: false
|
},
|
// 当调用对齐时,用来设置组件与组件之间的对齐距离,以像素为单位。
|
snapTolerance: {
|
type: Number,
|
default: 5,
|
validator: function(val) {
|
return typeof val === "number";
|
}
|
}
|
},
|
|
data: function() {
|
return {
|
top: this.y,
|
left: this.x,
|
width: this.w,
|
height: this.h,
|
resizing: false,
|
dragging: false,
|
enabled: this.active,
|
handle: null,
|
zIndex: this.z,
|
// 如果组件之间存在冲突,用来记录原位置信息
|
restoreY: 0,
|
restoreX: 0,
|
restoreW: 0,
|
restoreH: 0
|
};
|
},
|
|
computed: {
|
style: function() {
|
return {
|
top: this.top + "px",
|
left: this.left + "px",
|
width: this.width + "px",
|
height: this.height + "px",
|
zIndex: this.zIndex
|
};
|
}
|
},
|
|
watch: {
|
active: function(val) {
|
this.enabled = val;
|
},
|
z: function(val) {
|
if (val >= 0 || val === "auto") {
|
this.zIndex = val;
|
}
|
},
|
y: function(val) {
|
if (val >= 0) {
|
this.recording();
|
this.top = val;
|
this.conflictCheck();
|
this.reviewDimensions();
|
}
|
},
|
x: function(val) {
|
if (val >= 0) {
|
this.recording();
|
this.left = val;
|
this.conflictCheck();
|
this.reviewDimensions();
|
}
|
},
|
w: function(val) {
|
if (val >= 0) {
|
this.recording();
|
this.width = val;
|
this.conflictCheck();
|
this.reviewDimensions();
|
}
|
},
|
h: function(val) {
|
if (val >= 0) {
|
this.recording();
|
this.height = val;
|
this.conflictCheck();
|
this.reviewDimensions();
|
}
|
},
|
left: function(val) {
|
this.$emit("update:x", parseInt(val));
|
},
|
top: function(val) {
|
this.$emit("update:y", parseInt(val));
|
},
|
width: function(val) {
|
this.$emit("update:w", parseInt(val));
|
},
|
height: function(val) {
|
this.$emit("update:h", parseInt(val));
|
}
|
},
|
|
created: function() {
|
this.parentX = 0;
|
this.parentW = 9999;
|
this.parentY = 0;
|
this.parentH = 9999;
|
|
this.mouseX = 0;
|
this.mouseY = 0;
|
|
this.lastMouseX = 0;
|
this.lastMouseY = 0;
|
|
this.mouseOffX = 0;
|
this.mouseOffY = 0;
|
|
this.elmX = 0;
|
this.elmY = 0;
|
|
this.elmW = 0;
|
this.elmH = 0;
|
},
|
mounted: function() {
|
document.documentElement.addEventListener(
|
"mousemove",
|
this.handleMove,
|
true
|
);
|
document.documentElement.addEventListener("mousedown", this.deselect, true);
|
document.documentElement.addEventListener("mouseup", this.handleUp, true);
|
|
// touch events bindings
|
document.documentElement.addEventListener(
|
"touchmove",
|
this.handleMove,
|
true
|
);
|
document.documentElement.addEventListener(
|
"touchend touchcancel",
|
this.deselect,
|
true
|
);
|
document.documentElement.addEventListener(
|
"touchstart",
|
this.handleUp,
|
true
|
);
|
|
this.setSnap();
|
this.setConflictCheck();
|
this.getElmPosition();
|
|
this.reviewDimensions();
|
},
|
beforeDestroy: function() {
|
document.documentElement.removeEventListener(
|
"mousemove",
|
this.handleMove,
|
true
|
);
|
document.documentElement.removeEventListener(
|
"mousedown",
|
this.deselect,
|
true
|
);
|
document.documentElement.removeEventListener(
|
"mouseup",
|
this.handleUp,
|
true
|
);
|
|
// touch events bindings removed
|
document.documentElement.removeEventListener(
|
"touchmove",
|
this.handleMove,
|
true
|
);
|
document.documentElement.removeEventListener(
|
"touchend touchcancel",
|
this.deselect,
|
true
|
);
|
document.documentElement.removeEventListener(
|
"touchstart",
|
this.handleUp,
|
true
|
);
|
},
|
|
methods: {
|
// 设置对齐元素
|
setSnap: function() {
|
if (this.snap) {
|
this.$el.setAttribute("data-is-snap", "true");
|
} else {
|
this.$el.setAttribute("data-is-snap", "false");
|
}
|
},
|
// 检测对齐元素
|
snapCheck: function() {
|
if (this.snap) {
|
const p = this.$el.parentNode.childNodes; // 获取当前父节点下所有子节点
|
if (p.length > 1) {
|
const x1 = this.left;
|
const x2 = this.left + this.width;
|
const y1 = this.top;
|
const y2 = this.top + this.height;
|
for (let i = 0; i < p.length; i++) {
|
if (
|
p[i] !== this.$el &&
|
p[i].className !== undefined &&
|
p[i].getAttribute("data-is-snap") !== "false"
|
) {
|
const l = p[i].offsetLeft; // 对齐目标的left
|
const r = l + p[i].offsetWidth; // 对齐目标右侧距离窗口的left
|
const t = p[i].offsetTop; // 对齐目标的top
|
const b = t + p[i].offsetHeight; // 对齐目标右侧距离窗口的top
|
|
const ts = Math.abs(t - y2) <= this.snapTolerance;
|
const bs = Math.abs(b - y1) <= this.snapTolerance;
|
const ls = Math.abs(l - x2) <= this.snapTolerance;
|
const rs = Math.abs(r - x1) <= this.snapTolerance;
|
if (ts) {
|
this.top = t - this.height;
|
}
|
if (bs) {
|
this.top = b;
|
}
|
if (ls) {
|
this.left = l - this.width;
|
}
|
if (rs) {
|
this.left = r;
|
}
|
}
|
}
|
}
|
}
|
},
|
// 获得激活组件的位置信息
|
getElmPosition: function() {
|
this.elmX = parseInt(this.$el.style.left);
|
this.elmY = parseInt(this.$el.style.top);
|
this.elmW = this.$el.offsetWidth || this.$el.clientWidth;
|
this.elmH = this.$el.offsetHeight || this.$el.clientHeight;
|
},
|
// 设置冲突检测
|
setConflictCheck: function() {
|
if (this.isConflictCheck) {
|
this.$el.setAttribute("data-is-check", "true");
|
} else {
|
this.$el.setAttribute("data-is-check", "false");
|
}
|
},
|
// 冲突检测
|
conflictCheck: function() {
|
if (this.isConflictCheck) {
|
const p = this.$el.parentNode.childNodes; // 获取当前父节点下所有子节点
|
if (p.length > 1) {
|
for (let i = 0; i < p.length; i++) {
|
if (
|
p[i] !== this.$el &&
|
p[i].className !== undefined &&
|
p[i].getAttribute("data-is-check") !== "false"
|
) {
|
const tw = p[i].offsetWidth;
|
const th = p[i].offsetHeight;
|
const tl = p[i].offsetLeft;
|
const tt = p[i].offsetTop;
|
// 如果冲突,就将回退到移动前的位置
|
if (
|
(this.top >= tt &&
|
this.left >= tl &&
|
tt + th > this.top &&
|
tl + tw > this.left) ||
|
(this.top <= tt &&
|
this.left < tl &&
|
this.top + this.height > tt &&
|
this.left + this.width > tl)
|
) {
|
// 左上角与右下角重叠
|
this.top = this.restoreY;
|
this.left = this.restoreX;
|
this.width = this.restoreW;
|
this.height = this.restoreH;
|
} else if (
|
(this.left <= tl &&
|
this.top >= tt &&
|
this.left + this.width > tl &&
|
this.top < tt + th) ||
|
(this.top < tt &&
|
this.left > tl &&
|
this.top + this.height > tt &&
|
this.left < tl + tw)
|
) {
|
// 右上角与左下角重叠
|
this.top = this.restoreY;
|
this.left = this.restoreX;
|
this.width = this.restoreW;
|
this.height = this.restoreH;
|
} else if (
|
(this.top < tt &&
|
this.left <= tl &&
|
this.top + this.height > tt &&
|
this.left + this.width > tl) ||
|
(this.top > tt &&
|
this.left >= tl &&
|
this.top < tt + th &&
|
this.left < tl + tw)
|
) {
|
// 下边与上边重叠
|
this.top = this.restoreY;
|
this.left = this.restoreX;
|
this.width = this.restoreW;
|
this.height = this.restoreH;
|
} else if (
|
(this.top <= tt &&
|
this.left >= tl &&
|
this.top + this.height > tt &&
|
this.left < tl + tw) ||
|
(this.top >= tt &&
|
this.left <= tl &&
|
this.top < tt + th &&
|
this.left > tl + tw)
|
) {
|
// 上边与下边重叠(宽度不一样
|
this.top = this.restoreY;
|
this.left = this.restoreX;
|
this.width = this.restoreW;
|
this.height = this.restoreH;
|
} else if (
|
(this.left >= tl &&
|
this.top >= tt &&
|
this.left < tl + tw &&
|
this.top < tt + th) ||
|
(this.top > tt &&
|
this.left <= tl &&
|
this.left + this.width > tl &&
|
this.top < tt + th)
|
) {
|
// 左边与右边重叠
|
this.top = this.restoreY;
|
this.left = this.restoreX;
|
this.width = this.restoreW;
|
this.height = this.restoreH;
|
} else if (
|
(this.top <= tt &&
|
this.left >= tl &&
|
this.top + this.height > tt &&
|
this.left < tl + tw) ||
|
(this.top >= tt &&
|
this.left <= tl &&
|
this.top < tt + th &&
|
this.left + this.width > tl)
|
) {
|
// 左边与右边重叠(高度不一样)
|
this.top = this.restoreY;
|
this.left = this.restoreX;
|
this.width = this.restoreW;
|
this.height = this.restoreH;
|
}
|
}
|
}
|
}
|
}
|
},
|
// 检测尺寸
|
reviewDimensions: function() {
|
// if (this.minw > this.w) this.width = this.minw;
|
// if (this.minh > this.h) this.height = this.minh;
|
|
// if (this.parent) {
|
// const parentW = parseInt(this.$el.parentNode.clientWidth, 10);
|
// const parentH = parseInt(this.$el.parentNode.clientHeight, 10);
|
|
// this.parentW = parentW;
|
// this.parentH = parentH;
|
|
// if (this.w > this.parentW) this.width = parentW;
|
|
// if (this.h > this.parentH) this.height = parentH;
|
|
// if (this.x + this.w > this.parentW) this.width = parentW - this.x;
|
|
// if (this.y + this.h > this.parentH) this.height = parentH - this.y;
|
// }
|
|
// this.elmW = this.width;
|
// this.elmH = this.height;
|
|
// this.$emit("resizing", this.left, this.top, this.width, this.height);
|
},
|
// 鼠标激活当前组件
|
elmDown: function(e) {
|
const target = e.target || e.srcElement;
|
if (this.$el.contains(target)) {
|
target.tabIndex = 0;
|
target.focus();
|
if (
|
(this.dragHandle &&
|
!matchesSelectorToParentElements(
|
target,
|
this.dragHandle,
|
this.$el
|
)) ||
|
(this.dragCancel &&
|
matchesSelectorToParentElements(target, this.dragCancel, this.$el))
|
) {
|
return;
|
}
|
|
e.stopPropagation();
|
e.preventDefault();
|
|
this.reviewDimensions();
|
|
if (!this.enabled) {
|
this.enabled = true;
|
|
this.$emit("activated");
|
this.$emit("update:active", true);
|
}
|
// 激活区域块时获取当前区域块的X,Y,W,H
|
this.getElmPosition();
|
if (this.draggable) {
|
this.dragging = true;
|
this.recording();
|
}
|
}
|
},
|
// 取消激活
|
deselect: function(e) {
|
if (e.type.indexOf("touch") !== -1) {
|
this.mouseX = e.changedTouches[0].clientX;
|
this.mouseY = e.changedTouches[0].clientY;
|
} else {
|
this.mouseX =
|
e.pageX || e.clientX + document.documentElement.scrollLeft;
|
this.mouseY = e.pageY || e.clientY + document.documentElement.scrollTop;
|
}
|
|
this.lastMouseX = this.mouseX;
|
this.lastMouseY = this.mouseY;
|
|
const target = e.target || e.srcElement;
|
const regex = new RegExp("handle-([trmbl]{2})", "");
|
|
if (!this.$el.contains(target) && !regex.test(target.className)) {
|
if (this.enabled) {
|
this.enabled = false;
|
|
this.$emit("deactivated");
|
this.$emit("update:active", false);
|
}
|
}
|
},
|
// 鼠标按下控制点
|
handleDown: function(handle, e) {
|
this.handle = handle;
|
|
if (e.stopPropagation) e.stopPropagation();
|
if (e.preventDefault) e.preventDefault();
|
|
// 当区域块处于被激活状态时,手柄被点击时获取当前区域块的X,Y,W,H(如果不加进来,会出现区域块会跳动到回退前的位置)
|
this.getElmPosition();
|
|
this.recording();
|
// END
|
this.resizing = true;
|
},
|
// 最大化
|
fillParent: function(e) {
|
if (!this.parent || !this.resizable || !this.maximize) return;
|
|
let done = false;
|
|
const animate = () => {
|
if (!done) {
|
window.requestAnimationFrame(animate);
|
}
|
|
if (this.axis === "x") {
|
if (this.width === this.parentW && this.left === this.parentX) {
|
done = true;
|
}
|
} else if (this.axis === "y") {
|
if (this.height === this.parentH && this.top === this.parentY) {
|
done = true;
|
}
|
} else if (this.axis === "both") {
|
if (
|
this.width === this.parentW &&
|
this.height === this.parentH &&
|
this.top === this.parentY &&
|
this.left === this.parentX
|
) {
|
done = true;
|
}
|
}
|
|
if (this.axis === "x" || this.axis === "both") {
|
if (this.width < this.parentW) {
|
this.width++;
|
this.elmW++;
|
}
|
|
if (this.left > this.parentX) {
|
this.left--;
|
this.elmX--;
|
}
|
}
|
|
if (this.axis === "y" || this.axis === "both") {
|
if (this.height < this.parentH) {
|
this.height++;
|
this.elmH++;
|
}
|
|
if (this.top > this.parentY) {
|
this.top--;
|
this.elmY--;
|
}
|
}
|
|
this.$emit("resizing", this.left, this.top, this.width, this.height);
|
};
|
|
window.requestAnimationFrame(animate);
|
},
|
// 鼠标移动
|
handleMove: function(e) {
|
const isTouchMove = e.type.indexOf("touchmove") !== -1;
|
this.mouseX = isTouchMove
|
? e.touches[0].clientX
|
: e.pageX || e.clientX + document.documentElement.scrollLeft;
|
this.mouseY = isTouchMove
|
? e.touches[0].clientY
|
: e.pageY || e.clientY + document.documentElement.scrollTop;
|
|
let diffX = this.mouseX - this.lastMouseX + this.mouseOffX;
|
let diffY = this.mouseY - this.lastMouseY + this.mouseOffY;
|
|
this.mouseOffX = this.mouseOffY = 0;
|
|
this.lastMouseX = this.mouseX;
|
this.lastMouseY = this.mouseY;
|
|
const dX = diffX;
|
const dY = diffY;
|
|
if (this.resizing) {
|
if (this.handle.indexOf("t") >= 0) {
|
if (this.elmH - dY < this.minh) {
|
this.mouseOffY = dY - (diffY = this.elmH - this.minh);
|
} else if (this.parent && this.elmY + dY < this.parentY) {
|
this.mouseOffY = dY - (diffY = this.parentY - this.elmY);
|
}
|
this.elmY += diffY;
|
this.elmH -= diffY;
|
}
|
|
if (this.handle.indexOf("b") >= 0) {
|
if (this.elmH + dY < this.minh) {
|
this.mouseOffY = dY - (diffY = this.minh - this.elmH);
|
} else if (this.parent && this.elmY + this.elmH + dY > this.parentH) {
|
this.mouseOffY =
|
dY - (diffY = this.parentH - this.elmY - this.elmH);
|
}
|
this.elmH += diffY;
|
}
|
|
if (this.handle.indexOf("l") >= 0) {
|
if (this.elmW - dX < this.minw) {
|
this.mouseOffX = dX - (diffX = this.elmW - this.minw);
|
} else if (this.parent && this.elmX + dX < this.parentX) {
|
this.mouseOffX = dX - (diffX = this.parentX - this.elmX);
|
}
|
this.elmX += diffX;
|
this.elmW -= diffX;
|
}
|
|
if (this.handle.indexOf("r") >= 0) {
|
if (this.elmW + dX < this.minw) {
|
this.mouseOffX = dX - (diffX = this.minw - this.elmW);
|
} else if (this.parent && this.elmX + this.elmW + dX > this.parentW) {
|
this.mouseOffX =
|
dX - (diffX = this.parentW - this.elmX - this.elmW);
|
this.elmW += diffX;
|
}
|
this.elmW += diffX;
|
}
|
|
this.left = Math.round(this.elmX / this.grid[0]) * this.grid[0];
|
this.top = Math.round(this.elmY / this.grid[1]) * this.grid[1];
|
|
this.width = Math.round(this.elmW / this.grid[0]) * this.grid[0];
|
this.height = Math.round(this.elmH / this.grid[1]) * this.grid[1];
|
|
this.$emit("resizing", this.left, this.top, this.width, this.height);
|
} else if (this.dragging) {
|
if (this.parent) {
|
if (this.elmX + dX < this.parentX) {
|
this.mouseOffX = dX - (diffX = this.parentX - this.elmX);
|
} else if (this.elmX + this.elmW + dX > this.parentW) {
|
this.mouseOffX =
|
dX - (diffX = this.parentW - this.elmX - this.elmW);
|
}
|
|
if (this.elmY + dY < this.parentY) {
|
this.mouseOffY = dY - (diffY = this.parentY - this.elmY);
|
} else if (this.elmY + this.elmH + dY > this.parentH) {
|
this.mouseOffY =
|
dY - (diffY = this.parentH - this.elmY - this.elmH);
|
}
|
}
|
|
this.elmX += diffX;
|
this.elmY += diffY;
|
|
if (this.axis === "x" || this.axis === "both") {
|
this.left = Math.round(this.elmX / this.grid[0]) * this.grid[0];
|
}
|
if (this.axis === "y" || this.axis === "both") {
|
this.top = Math.round(this.elmY / this.grid[1]) * this.grid[1];
|
}
|
this.snapCheck();
|
this.$emit("dragging", this.left, this.top);
|
}
|
},
|
// 键盘操作
|
handleKeyDown: function(e) {
|
let dX = 0;
|
let dY = 0;
|
if (e.keyCode === 39) {
|
// 右键
|
dX = 1;
|
} else if (e.keyCode === 37) {
|
// 左键
|
dX = -1;
|
} else if (e.keyCode === 38) {
|
// 上键
|
dY = -1;
|
} else if (e.keyCode === 40) {
|
// 下键
|
dY = 1;
|
}
|
|
if (this.draggable) {
|
this.elmX += dX;
|
this.elmY += dY;
|
|
if (this.axis === "x" || this.axis === "both") {
|
this.left = Math.round(this.elmX / this.grid[0]) * this.grid[0];
|
}
|
if (this.axis === "y" || this.axis === "both") {
|
this.top = Math.round(this.elmY / this.grid[1]) * this.grid[1];
|
}
|
this.snapCheck();
|
this.$emit("keydown", this.left, this.top);
|
}
|
},
|
// 鼠标松开
|
handleUp: function(e) {
|
if (e.type.indexOf("touch") !== -1) {
|
this.lastMouseX = e.changedTouches[0].clientX;
|
this.lastMouseY = e.changedTouches[0].clientY;
|
}
|
this.handle = null;
|
if (this.resizing) {
|
this.resizing = false;
|
this.conflictCheck(); // 冲突检测
|
this.$emit("resizestop", this.left, this.top, this.width, this.height);
|
}
|
if (this.dragging) {
|
this.dragging = false;
|
this.conflictCheck(); // 冲突检测
|
this.$emit("dragstop", this.left, this.top);
|
}
|
|
this.elmX = this.left;
|
this.elmY = this.top;
|
},
|
// 将移动前的位置存储
|
recording: function() {
|
this.restoreY = this.top;
|
this.restoreX = this.left;
|
this.restoreW = this.width;
|
this.restoreH = this.height;
|
}
|
}
|
};
|
</script>
|
|
<style scoped>
|
.vdr {
|
position: absolute;
|
box-sizing: border-box;
|
}
|
.handle {
|
box-sizing: border-box;
|
display: none;
|
position: absolute;
|
width: 4px;
|
height: 4px;
|
font-size: 1px;
|
background: #eee;
|
border: 1px solid #333;
|
z-index: 999;
|
}
|
.handle-tl {
|
top: -2px;
|
left: -2px;
|
cursor: nw-resize;
|
}
|
.handle-tm {
|
top: -2px;
|
left: 50%;
|
margin-left: -2px;
|
cursor: n-resize;
|
}
|
.handle-tr {
|
top: -2px;
|
right: -2px;
|
cursor: ne-resize;
|
}
|
.handle-ml {
|
top: 50%;
|
margin-top: -2px;
|
left: -2px;
|
cursor: w-resize;
|
}
|
.handle-mr {
|
top: 50%;
|
margin-top: -2px;
|
right: -2px;
|
cursor: e-resize;
|
}
|
.handle-bl {
|
bottom: -2px;
|
left: -2px;
|
cursor: sw-resize;
|
}
|
.handle-bm {
|
bottom: -2px;
|
left: 50%;
|
margin-left: -2px;
|
cursor: s-resize;
|
}
|
.handle-br {
|
bottom: -2px;
|
right: -2px;
|
cursor: se-resize;
|
}
|
@media only screen and (max-width: 768px) {
|
/* For mobile phones: */
|
[class*="handle-"]:before {
|
content: "";
|
left: -4px;
|
right: -4px;
|
bottom: -4px;
|
top: -4px;
|
position: absolute;
|
}
|
}
|
</style>
|