jQuery-ui를 사용하여 드래그 이벤트와 리사이즈 이벤트를 추가 할 수 있는데, 직사각형의 영역을 서로 침범할 경우 기존 위치로 원위치 시키는 방법을 알아보겠습니다.
겹침 처리 방법
1. 일반 2차원 배열에 0으로 채워넣고, 도형이 있는 위치는 1로 채웁니다.
![](./files/attach/images/289019/869/306/b75db9f91e7fd52dab5314c605585fa0.png)
2. 도형 위치마다 1로 더하기때문에 겹치는 영역이 생기면 아래처럼 2가 존재하게 됩니다.
![](./files/attach/images/289019/869/306/5d0e91927071466976896a4b6b384831.png)
3. 각 도형마다의 위치와 넓이, 높이를 기억하고 있다가 겹치면 원위치 시킨다.
실적용 소스
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/smoothness/jquery-ui.css">
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<style>
* {
margin: 0;
padding: 0
}
#box {
width: 500px;
height: 500px;
border: 1px solid black;
background: #eee;
}
#box .rect {
position: absolute;
width: 50px;
height: 50px;
border: 1px solid black;
}
</style>
</head>
<body>
<div id="box">
<div class="rect" idx=0></div>
<div class="rect" idx=1></div>
</div>
<script src="./draggable_rect.js"></script>
</body>
</html>
draggable_rect.js
var rectArr = [];
var canvasArr = [];
$(function () {
//초기 세팅
for (i = 0; i < $(".rect").length; i++) {
var rect = $($(".rect")[i])
var idx = rect.attr("idx");
var x = rect.offset().left;
var y = rect.offset().top;
var left = rect.css("left");
var top = rect.css("top");
var w = rect.width();
var h = rect.height();
rectArr[idx] = { x: x, y: y, left: left, top: top, w: w, h: h };
}
var width = $("#box").width();
var height = $("#box").height();
for (i = 0; i < height; i++) {
canvasArr[i] = new Array(width);
}
for (i = 0; i < height; i++) {
for (j = 0; j < width; j++) {
canvasArr[i][j] = 0;
}
}
});
$(".rect").draggable({
containment: "parent",
start: function (event, ui) {
},
stop: function (event, ui) {
var idx = $(this).attr("idx");
var left = $(this).css("left");
var top = $(this).css("top");
var x = $(this).offset().left;
var y = $(this).offset().top;
var w = $(this).width();
var h = $(this).height();
var thisObj = { x: x, y: y, w: w, h: h, idx: idx };
if (overLapChecker(".rect", thisObj)) {
//통과
rectArr[idx] = { x: x, y: y, left: left, top: top, w: w, h: h };
} else {
//겹침 - 초기화
var obj = rectArr[idx];
$(".rect[idx=" + idx + "]").css("top", obj.top);
$(".rect[idx=" + idx + "]").css("left", obj.left);
}
}
}).resizable({
containment: "parent",
start: function (event, ui) {
},
stop: function (event, ui) {
var idx = $(this).attr("idx");
var left = $(this).css("left");
var top = $(this).css("top");
var x = $(this).offset().left;
var y = $(this).offset().top;
var w = $(this).width();
var h = $(this).height();
var thisObj = { x: x, y: y, w: w, h: h, idx: idx };
if (overLapChecker(".rect", thisObj)) {
//통과
rectArr[idx] = { x: x, y: y, left: left, top: top, w: w, h: h };
} else {
//겹침 - 초기화
var obj = rectArr[idx];
$(".rect[idx=" + idx + "]").css("top", obj.top);
$(".rect[idx=" + idx + "]").css("left", obj.left);
$(".rect[idx=" + idx + "]").css("width", obj.w);
$(".rect[idx=" + idx + "]").css("height", obj.h);
}
}
})
function overLapChecker(className, thisObj) {
var len = $(className).length;
if (len > 0) {
var thisMapArr = JSON.parse(JSON.stringify(canvasArr)); //빈 배열을 복사한다.
var x = thisObj.x;
var y = thisObj.y;
var w = thisObj.w;
var h = thisObj.h;
for (i = y; i < y + h; i++) {
for (j = x; j < x + w; j++) {
thisMapArr[i][j] = thisMapArr[i][j] + 1;
}
}
for (z = 0; z < len; z++) {
var idx = $($(className)[z]).attr("idx");
if (idx == thisObj.idx) {
continue;
} else {
var checkerArr = JSON.parse(JSON.stringify(thisMapArr));
var x2 = $(".rect[idx=" + idx + "]").offset().left;
var y2 = $(".rect[idx=" + idx + "]").offset().top;
var w2 = $(".rect[idx=" + idx + "]").width();
var h2 = $(".rect[idx=" + idx + "]").height();
for (i = y2; i < y2 + h2; i++) {
for (j = x2; j < x2 + w2; j++) {
checkerArr[i][j] = checkerArr[i][j] + 1;
if (checkerArr[i][j] > 1) {
return false;
}
}
}
}
}
}
return true;
}
드래그, 리사이즈 이벤트 처리를 하고 각 도형의 위치를 특정 배열에 담아둡니다.
드래그 또는 리사이즈 이벤트가 멈추면 멈추는 동시에 위치를 체크합니다. 겹치는 동선이 존재하여 배열에(2)가 처리되면 원위치 시킵니다.
적용 모습
![](./files/attach/images/289019/869/306/4e2688c35e54e7c3b204476f3823a4b8.gif)