首页 > 解决方案 > 当我想给元素随机绝对位置时,如何防止元素重叠

问题描述

嗨,我有 5 个方格,我想给它们随机的左上角位置,但是给它们随机位置可能会产生这样的问题:

在此处输入图像描述

这是我的代码:

let container = document.querySelector(".container");
let squares = document.querySelectorAll(".square");


let pageWidth = container.getBoundingClientRect().width;
let pageHeight = container.getBoundingClientRect().height;

let width;

squares.forEach((square) => {

  width = Math.floor(Math.random() * 25) + 30;
  square.style.width = width + "px";
  square.style.height = width + "px";
  square.style.position = "absolute";
  square.style.top = Math.floor(Math.random() * (pageHeight - 200)) + "px";
  square.style.left = Math.floor(Math.random() * (pageWidth - 200)) + "px";

});
.container {
  position: relative;
  width: 100%;
  height: 100vh;
}

.square:nth-child(1) {
  background-color: #142bc5;
}

.square:nth-child(2) {
  background-color: #37d437;
}

.square:nth-child(3) {
  background-color: #c52f14;
}

.square:nth-child(4) {
  background-color: #c5149f;
}

.square:nth-child(5) {
  background-color: #38c514;
}
<div class="container">
  <div class="square"></div>
  <div class="square"></div>
  <div class="square"></div>
  <div class="square"></div>
  <div class="square"></div>
</div>

我怎样才能防止这个问题?

标签: javascripthtmlcssposition

解决方案


您需要记录已在页面上绘制框的位置以及它们的大小。然后,您需要在绘制后续框时检查碰撞/重叠。

这是一个代码示例,它使用此 Stack Overflow 答案来确定框是否重叠。

代码

const container = document.querySelector(".container");
const squares = document.querySelectorAll(".square");

const {width: pageWidth, height: pageHeight} = container.getBoundingClientRect();

const drawnSquares = [];

squares.forEach((square) => {
  // Since this is a square, width and height are equal
  const {width, top, left} = getRandomSquare();
  square.style.width = `${width}px`;
  square.style.height = `${width}px`;
  square.style.top = `${top}px`;
  square.style.left = `${left}px`;
  drawnSquares.push({
    width,
    top,
    left,
    bottom: top + width,
    right: left + width
  });
});

function getRandomSquare() {
  const width = Math.floor(Math.random() * 25) + 30;
  const top = Math.floor(Math.random() * (pageHeight - width));
  const left = Math.floor(Math.random() * (pageWidth - width));
  const square = {width, top, left};
  if (!overlapsWithAny(square)) {
    // We've got a good square, return it
    return square;
  } else {
    // Our square overlaps with one that's already on the page
    // so we should generate a new square
    return getRandomSquare();
  }
}

function overlapsWithAny(square) {
  if (drawnSquares.length === 0) {
    return false;
  } else {
    return drawnSquares.some(ds => {
      // Based on https://stackoverflow.com/a/12067046/2176546
      return !(square.right < ds.left || 
                  square.left > ds.right || 
                  square.bottom < ds.top || 
                  square.top > ds.bottom);
    })
  }
}
body {
  margin: 0;
  padding: 0;
  width: 100vw;
  height: 100vh;
}

.container {
  position: relative;
  width: 100vw;
  height: 100vh;
}

.square {
  position: absolute;
}

.square:nth-child(1) {
  background-color: #142bc5;
}

.square:nth-child(2) {
  background-color: #37d437;
}

.square:nth-child(3) {
  background-color: #c52f14;
}

.square:nth-child(4) {
  background-color: #c5149f;
}

.square:nth-child(5) {
  background-color: #38c514;
}
<div class="container">
  <div class="square"></div>
  <div class="square"></div>
  <div class="square"></div>
  <div class="square"></div>
  <div class="square"></div>
</div>

请注意我如何添加body {margin: 0; padding: 0}到样式表以使其100vh正常100vw工作。


推荐阅读