最近公司开发图片组合(React),选择的图片要求可以拖拽位置、拉伸大小,就用原生js写了一个,代码就不做太多修改(es6语法,需要的自行修改,可直接运行),有需要的可以直接拿去(为了防止图片拖拽出区域,有限制区域大小,可以自行修改)。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
</head>
<style>
/* 拖拽,缩放组件相关class */
.drage_box {
position: absolute;
}
.drage_box > img {
width: 100%;
height: 100%;
cursor: all-scroll;
}
/* 四个边以及4个顶点 */
.drage_top,
.drage_right,
.drage_bottom,
.drage_left {
position: absolute;
z-index: 1;
background: #666;
}
/* 左右高度100% */
.drage_left,
.drage_right {
width: 2px;
height: 100%;
cursor: w-resize;
background-image: linear-gradient(
to bottom,
#fff 0%,
#ccc 50%,
transparent 50%
);
background-size: 2px 20px;
background-repeat: repeat-y;
}
/* 上下宽度100% */
.drage_top,
.drage_bottom {
width: 100%;
height: 2px;
cursor: n-resize;
background-image: linear-gradient(
to right,
#fff 0%,
#ccc 50%,
transparent 50%
);
background-size: 20px 2px;
background-repeat: repeat-x;
}
.drage_top {
top: 0;
}
.drage_right {
right: 0;
}
.drage_bottom {
bottom: 0;
}
.drage_left {
left: 0;
}
/* 四个角 */
.drage_top_right,
.drage_top_left,
.drage_bottom_right,
.drage_bottom_left {
width: 6px;
height: 6px;
position: absolute;
background: #fff;
z-index: 2;
}
.drage_top_right {
right: -2px;
top: -2px;
cursor: nesw-resize;
}
.drage_top_left {
left: -2px;
top: -2px;
cursor: nwse-resize;
}
.drage_bottom_right {
right: -2px;
bottom: -2px;
cursor: nwse-resize;
}
.drage_bottom_left {
left: -2px;
bottom: -2px;
cursor: nesw-resize;
}
/* 删除图标 */
.drage_box_delete {
position: absolute;
top: -16px;
right: -16px;
border-radius: 50%;
width: 16px;
height: 16px;
line-height: 16px;
vertical-align: middle;
text-align: center;
color: #fff;
cursor: pointer;
background: #ff606c;
z-index: 1;
}
</style>
<body>
<div class="drage_box" id="xxDrageBox">
<span class="drage_top"></span>
<span class="drage_right"></span>
<span class="drage_bottom"></span>
<span class="drage_left"></span>
<span class="drage_top_right"></span>
<span class="drage_top_left"></span>
<span class="drage_bottom_right"></span>
<span class="drage_bottom_left"></span>
<img id="xxDrageImage" draggable="false" src="https://cn.bing.com/th?id=OHR.BardenasDesert_ZH-CN1357611840_1920x1080.jpg&rf=LaDigue_1920x1080.jpg&pid=hp" />
</div>
</body>
<script>
window.onload = () => {
const xx_box = document.getElementById("xxDrageBox");
const xx_img = document.getElementById("xxDrageImage");
// 给4个角和4个边绑定拖拉方法(只改变大小)
const xx_drag_border = xx_box.getElementsByTagName("span");
new Array(xx_drag_border.length)
.fill(1)
.forEach((item, index) =>
this.drag(xx_box, xx_drag_border[index], index)
);
// 给图片绑定拖拽方法(只改变位置)
xx_img.onmousedown = event => {
if (this._isUnMount) {
return;
}
/*再次点击时使得图标任然在那个位置,鼠标可以点击到图标上*/
const ol = event.clientX - xx_box.offsetLeft;
const ot = event.clientY - xx_box.offsetTop;
/*鼠标点击*/
document.onmousemove = event => {
xx_box.style.left = event.clientX - ol + "px"; /*赋值*/
xx_box.style.top = event.clientY - ot + "px";
};
/*鼠标松开*/
document.onmouseup = event => {
document.onmousemove = () => this.limitDragAxis(xx_box);
document.onmouseup = null;
};
};
};
function drag(box, obj, index) {
obj.onmousedown = ev => {
if (this._isUnMount) {
return;
}
const oEv = ev || event;
// 获取初始宽高
const oldWidth = box.offsetWidth;
const oldHeight = box.offsetHeight;
// 获取初始位置(top、left)
const oldLeft = box.offsetLeft;
const oldTop = box.offsetTop;
// 获取鼠标的坐标
const oldX = oEv.clientX;
const oldY = oEv.clientY;
document.onmousemove = ev => {
const oEv = ev || event;
// 顺序:上右下左 上右、上左、下右、下左
switch (index) {
case 0:
box.style.height = oldHeight - (oEv.clientY - oldY) + "px";
box.style.top = oldTop + (oEv.clientY - oldY) + "px";
break;
case 1:
box.style.height = oldHeight + "px";
box.style.width = oldWidth + (oEv.clientX - oldX) + "px";
box.style.right = oldLeft - (oEv.clientX - oldX) + "px";
break;
case 2:
box.style.height = oldHeight + (oEv.clientY - oldY) + "px";
box.style.bottom = oldTop - (oEv.clientY + oldY) + "px";
break;
case 3:
box.style.height = oldHeight + "px";
box.style.width = oldWidth - (oEv.clientX - oldX) + "px";
box.style.left = oldLeft + (oEv.clientX - oldX) + "px";
break;
case 4:
box.style.width = oldWidth + (oEv.clientX - oldX) + "px";
box.style.height = oldHeight - (oEv.clientY - oldY) + "px";
box.style.right = oldLeft - (oEv.clientX - oldX) + "px";
box.style.top = oldTop + (oEv.clientY - oldY) + "px";
break;
case 5:
box.style.width = oldWidth - (oEv.clientX - oldX) + "px";
box.style.height = oldHeight - (oEv.clientY - oldY) + "px";
box.style.left = oldLeft + (oEv.clientX - oldX) + "px";
box.style.top = oldTop + (oEv.clientY - oldY) + "px";
break;
case 6:
box.style.width = oldWidth + (oEv.clientX - oldX) + "px";
box.style.height = oldHeight + (oEv.clientY - oldY) + "px";
box.style.right = oldLeft - (oEv.clientX - oldX) + "px";
box.style.bottom = oldTop + (oEv.clientY + oldY) + "px";
break;
case 7:
box.style.width = oldWidth - (oEv.clientX - oldX) + "px";
box.style.height = oldHeight + (oEv.clientY - oldY) + "px";
box.style.left = oldLeft + (oEv.clientX - oldX) + "px";
box.style.bottom = oldTop + (oEv.clientY + oldY) + "px";
break;
default:
break;
}
this.drawImage();
};
document.onmouseup = () => {
if (this._isUnMount) {
return;
}
document.onmousemove = () => this.limitDragAxis(box);
};
return false;
};
}
// 计算拖拽的最大范围
function limitDragAxis(box) {
// 计算最大x和y
const width = 1920;
const height = 1080;
// 移除px
const rmPX = str => (str ? str.replace(/px$/, "") : 0);
const [top, left, _width, _height] = [
rmPX(box.style.top),
rmPX(box.style.left),
rmPX(box.style.width),
rmPX(box.style.height)
];
if (top > height) {
box.style.top = height - 20 + "px";
} else if (left + _width < 0) {
box.style.left = 20 - _width + "px";
} else if (left > width) {
box.style.left = width - 20 + "px";
} else if (top + _height < 0) {
box.style.top = 20 - _height + "px";
}
return;
}
</script>
</html>
预览图如下: