效果如图
代码如下:
<template>
<div>
<div
ref="dragRef"
:class="['es-drager', { dragerbor: selected }]"
:style="dragStyle"
@mousedown="onMousedown"
>
<img src="../../assets//images/qianming.svg" :style="dragStyle" />
<div v-show="selected">
<div
v-for="item in dotList"
:key="item.side"
class="es-drager-dot"
:data-side="item.side"
:style="getDotStyle(item)"
@mousedown="onDotMousedown(item, $event)"
></div>
</div>
</div>
</div>
</template>
<script>
export default {
name: "MyprojectScale",
data() {
return {
selected: true,
isMousedown:false,
dotList: [
{ side: "top", cursor: "n-resize" },
{ side: "bottom", cursor: "n-resize" },
{ side: "left", cursor: "e-resize" },
{ side: "right", cursor: "e-resize" },
{ side: "top-left", cursor: "se-resize" },
{ side: "top-right", cursor: "sw-resize" },
{ side: "bottom-left", cursor: "sw-resize" },
{ side: "bottom-right", cursor: "se-resize" },
],
dragData: {
width: 100,
height: 100,
left: 0,
top: 0,
},
};
},
mounted() {},
computed: {
dragStyle: function () {
const { width, height, left, top } = this.dragData;
return {
width: parseInt(width) + "px",
height: parseInt(height) + "px",
left: parseInt(left) + "px",
top: parseInt(top) + "px",
//"--es-drager-color": props.color,
};
},
},
methods: {
onMousedown(e) {
this.isMousedown= true;
const el = this.$refs.dragRef;
// 记录按下的位置
const downX = e.clientX;
const downY = e.clientY;
const elRect = el.getBoundingClientRect();
// 鼠标在盒子里的位置
const mouseX = downX - elRect.left;
const mouseY = downY - elRect.top;
const onMousemove = (e) => {
// 当前鼠标的位置减去鼠标在盒子里的位置就是要移动的距离
let moveX = e.clientX - mouseX;
let moveY = e.clientY - mouseY;
this.dragData.left = moveX;
this.dragData.top = moveY;
//emit && emit("move", dragData.value);
};
const onMouseup = (_e) => {
this.isMousedown= false;
// 移除document事件
document.removeEventListener("mousemove", onMousemove);
document.removeEventListener("mouseup", onMouseup);
};
// 位document注册鼠标移动事件
document.addEventListener("mousemove", onMousemove);
// 鼠标抬起事件
document.addEventListener("mouseup", onMouseup);
},
getDotStyle(item) {
const [side, position] = item.side.split("-");
const style = { [side]: "0%", cursor: item.cursor };
if (!position) {
const side2 = ["top", "bottom"].includes(side) ? "left" : "top";
style[side2] = "50%";
} else {
style[position] = "0%";
}
return style;
},
onDotMousedown(dotInfo, e) {
e.stopPropagation();
e.preventDefault();
// 获取鼠标按下的坐标
const downX = e.clientX;
const downY = e.clientY;
const el = this.$refs.dragRef;
const elRect = el.getBoundingClientRect();
console.log("elRect", elRect);
const onMousemove = (e) => {
// 移动的x距离
const disX = e.clientX - downX;
// 移动的y距离
const disY = e.clientY - downY;
const [side, position] = dotInfo.side.split("-");
// 是否是上方缩放圆点
const hasT = side === "top";
// 是否是左方缩放圆点
const hasL = [side, position].includes("left");
let width = elRect.width + (hasL ? -disX : disX);
let height = elRect.height + (hasT ? -disY : disY);
// 如果是左侧缩放圆点,修改left位置
let left = elRect.left + (hasL ? disX : 0);
// 如果是上方缩放圆点,修改top位置
let top = elRect.top + (hasT ? disY : 0);
if (!position) {
// 如果是四个正方位
if (["top", "bottom"].includes(side)) {
// 上下就不改变宽度
width = elRect.width;
} else {
// 左右就不改变高度
height = elRect.height;
}
}
// 处理逆向缩放
if (width < 0) {
width = -width;
left -= width;
}
if (height < 0) {
height = -height;
top -= height;
}
this.dragData = { left, top, width, height };
};
const onMouseup = (_e) => {
document.removeEventListener("mousemove", onMousemove);
document.removeEventListener("mouseup", onMouseup);
};
document.addEventListener("mousemove", onMousemove);
document.addEventListener("mouseup", onMouseup);
},
},
};
</script>
<style lang="scss" scoped>
.es-drager {
position: absolute;
z-index: 1000;
}
.dragerbor {
border: 1px solid #3a7afe;
}
.es-drager-dot {
position: absolute;
width: 8px;
height: 8px;
//border-radius: 50%;
background-color: #3a7afe;
transform: translate(-50%, -50%);
cursor: se-resize;
&[data-side*="right"] {
transform: translate(50%, -50%);
}
&[data-side*="bottom"] {
transform: translate(-50%, 50%);
}
&[data-side="bottom-right"] {
transform: translate(50%, 50%);
}
}
</style>