-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Description
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
body {
height: 100vh;
margin: 0;
display: flex;
flex-direction: column;
}
.tools {
list-style-type: none;
overflow: hidden;
border: 1px solid #000;
padding: 0;
margin: 0;
}
.tools li {
float: left;
border-left: 1px solid #000;
border-right: 1px solid #000;
margin-left: -1px;
cursor: pointer;
}
.canvas {
flex: 1;
border: 1px solid #000;
margin-top: -1px;
background: #fafafa;
}
.item {
background: white;
display: flex;
align-items: center;
justify-content: center;
min-height: 100px;
display: flex;
align-items: center;
justify-content: center;
margin: 10px;
}
/* .item::after {
content: attr(data-type);
} */
.placeholder {
background: rgba(0, 0, 0, 0.2);
position: absolute;
pointer-events: none;
}
.row {
margin: 0;
display: flex;
}
.col {
flex: 1;
}
</style>
</head>
<body>
<ul class="tools">
<li class="tools__item" draggable="true" data-type="icon">
<img
src="https://gw.alipayobjects.com/zos/alisis/8c6cfe1e-7d50-49c2-b633-34e7434ce938/tubiaoditu-normal-v3.svg"
alt=""
/>
</li>
<li class="tools__item" draggable="true" data-type="area">
<img
src="https://gw.alipayobjects.com/zos/dasbi_op/official-battle-map/icon20210308163342.png"
alt=""
/>
</li>
</ul>
<div class="canvas"></div>
<div class="placeholder"></div>
<script>
const placeholder = document.querySelector(".placeholder");
const toolsContainer = document.querySelector(".tools");
const lis = document.querySelectorAll(".tools li");
const canvas = document.querySelector(".canvas");
let type = "";
let url = "";
let dropTarget;
function getTarget(path, className) {
let target;
let index = 0;
while (index < path.length - 1) {
try {
if (path[index].classList?.contains(className)) {
target = path[index];
break;
}
index++;
} catch (e) {
console.log(path, className, index);
throw e;
}
}
return target;
}
canvas.addEventListener("dragover", (e) => {
e.preventDefault();
if (e.target === canvas) {
dropTarget = canvas;
// placeholder.style.width = `${canvas.offsetWidth}px`;
placeholder.style.height = `${100}px`;
placeholder.style.display = "block";
const last = canvas.lastChild;
if (last) {
placeholder.style.top = `${
last.offsetTop + 10 + last.offsetHeight
}px`;
} else {
placeholder.style.top = `${
(last ? last.offsetTop : canvas.offsetTop) + 10
}px`;
}
placeholder.style.width = "auto";
placeholder.style.left = "10px";
placeholder.style.right = "10px";
} else {
dropTarget = getTarget(e.path, "item");
if (dropTarget) {
const width = dropTarget.offsetWidth;
const x = e.pageX - dropTarget.offsetLeft;
const bounding = dropTarget.getBoundingClientRect();
if (x < width / 2) {
placeholder.style.left = `${bounding.left}px`;
placeholder.style.top = `${bounding.top}px`;
placeholder.style.width = `${bounding.width / 2}px`;
placeholder.style.height = `${bounding.height}px`;
} else {
placeholder.style.left = `${
bounding.left + bounding.width / 2
}px`;
placeholder.style.top = `${bounding.top}px`;
placeholder.style.width = `${bounding.width / 2}px`;
placeholder.style.height = `${bounding.height}px`;
}
placeholder.style.display = "block";
} else {
dropTarget = null;
}
}
});
canvas.addEventListener("dragend", () => {
placeholder.style.display = "none";
});
canvas.addEventListener("dragleave", () => {
placeholder.style.display = "none";
});
canvas.addEventListener("drop", (e) => {
e.preventDefault();
if (!dropTarget) {
return;
}
const item = document.createElement("div");
const img = document.createElement("img");
img.src = url;
item.appendChild(img);
item.style.background = `hsla(${Math.random() * 360},50%,50%, 1)`;
item.classList.add("item");
item.dataset.type = type;
type = "";
if (dropTarget === canvas) {
dropTarget.appendChild(item);
} else {
const row = document.createElement("div");
const col1 = document.createElement("div");
const col2 = document.createElement("div");
row.classList.add("row");
col1.classList.add("col");
col2.classList.add("col");
row.appendChild(col1);
row.appendChild(col2);
col1.appendChild(dropTarget.cloneNode(true));
col2.appendChild(item);
dropTarget.parentElement.replaceChild(row, dropTarget);
}
placeholder.style.display = "none";
});
toolsContainer.addEventListener("dragstart", (e) => {
const target = getTarget(e.path, "tools__item");
type = target.dataset.type;
url = target.firstElementChild.src;
});
</script>
</body>
</html>Metadata
Metadata
Assignees
Labels
No labels