1

Hi I have 5 squares and I want to give randomly position left and top to them but giving randomly position to them can make a problem like this:

enter image description here

and this is my code:

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>

how can I prevent this issue?

terrymorse
  • 6,771
  • 1
  • 21
  • 27
  • 3
    Try saving the position and width of all previous squares, and on every iteration check if the current position overlaps with any previous ones. If overlaps -> retry. – Abbas Akhundov Dec 25 '20 at 18:30

2 Answers2

3

You need to keep a record of where boxes have already been drawn on the page and how large they are. You then need to check for collisions / overlaps when you draw subsequent boxes.

Here's a code sample that uses this Stack Overflow answer to determine whether or not boxes overlap.

Code

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>

Note how I added body {margin: 0; padding: 0} to the stylesheet to make 100vh and 100vw work properly.

Robbie JW
  • 729
  • 1
  • 9
  • 22
0

as the answer by Robbie JW mentioned you need to apply a function to detect collisions , there is a very helpful function also you can find in this answer