Skip to content

低代码思路 #20

@taoeer

Description

@taoeer
<!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

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions