Create unique divs without any overlap

I am working on a project that involves TypeScript and React. The goal is to generate a new <div> with random width and height (between 50 and 300px) placed randomly within a wrapper (1920x1080).

The objective is to ensure that the newly created div does not overlap with existing ones. If there is no overlap, the element is created. Otherwise, a new position and size are generated until the space is filled without overlapping.

I have successfully written code for generating random positions and sizes. However, I am facing challenges in checking collisions and displaying a message when there is no empty space left.

const [count,setCount]=useState(0)
  const wrapper = document.getElementById('wrapper');
  var posX:number,posY:number,divSizeH:number,divSizeW:number;
  var willOverlap:boolean=false;
  function createRandomRectangle(){
    divSizeW = Math.round(((Math.random()*250) + 50));
    divSizeH = Math.round(((Math.random()*250) + 50));
    if (wrapper!=null) {
      const width = wrapper.offsetWidth , height = wrapper.offsetHeight;
      posX = Math.round( (Math.random() * ( width - divSizeW )) );
      posY = Math.round( (Math.random() * ( height - divSizeH )) );
       //checking collision
    document.querySelectorAll('.Rectangle').forEach(element=>{
          var r2 = element.getBoundingClientRect();
            if((posX <= r2.x && r2.x <= posX+divSizeW) && (posY <= r2.y && r2.y <= posY+divSizeH) ||
            (posX <= r2.x && r2.x <= posX+divSizeW) && (posY <= r2.bottom && r2.bottom <= posY+divSizeH) ||
            (posX <= r2.x+r2.height && r2.x+r2.height <= posX+divSizeW) && (posY <= r2.y+r2.width && r2.y+r2.width <= posY+divSizeW) ||
            (posX <= r2.x+r2.height &...
        })
    }
      
  
    //if there is no more place send message and dont create....
      const newDiv = document.createElement('div');
      newDiv.classList.add('Rectangle');
      newDiv.style.width=divSizeW+"px";
      newDiv.style.height=divSizeH+"px";
      newDiv.style.left=posX+"px";
      newDiv.style.top=posY+"px";
      boxxy?.appendChild(newDiv);
      setCount(count+1);
    
      
  }

Answer №1

When trying to solve the issue of collisions in your code, it is important to note that simply repeating the process with new positions and sizes may not guarantee a solution.

By implementing this repetition within a loop of existing Rectangles, there is a risk of not checking the newly generated position against all previous Rectangles, potentially resulting in overlapping elements.

Furthermore, detecting when your container is full and can no longer accommodate new Rectangles adds complexity to the problem. For now, let's focus on a simpler solution by limiting the number of repetitions.

To simplify the algorithm, consider the following approach:

const existingRectangles = document.querySelectorAll('.Rectangle');
let repCount = 0; // Number of repetitions

do {
  var overlapping = false;
  var newPositionAndSize = generateRandomPositionAndSize();

  for (let i = 0: i < existingRectangles.length; i += 1) {
    if (checkCollision(existingRectangles[i], newPositionAndSize)) {
      overlapping = true;
      repCount += 1;
      break;
    }
  }
} while (overlapping && repCount < 1000);

if (overlapping) {
  showMessageWrapperIsFull();
} else {
  createNewRectangleAndInsertIt(newPositionAndSize);
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Numerous documents within a JavaScript application

As a newcomer to JavaScript, I've been experimenting with the language to enhance my understanding. One aspect that puzzles me is how developers organize large JavaScript programs. In languages like Java, breaking down code into smaller files is commo ...

Tips on maintaining the functionality of the :hover selector even after loading a PDF document

Recently, I noticed an issue with an anchor element that is used to load a PDF. Once the PDF loads, the :hover styling seems to get stuck until I click elsewhere on the screen, which then resets it back to normal. Surprisingly, there is no JavaScript inv ...

Empty vertical space on the right side in iPad view

I am currently working on the development of this website and facing an issue. https://i.sstatic.net/Y7B7Q.png When switching to iPad view in Chrome's developer mode, I noticed a blank column on the extreme right side that spans the entire page. I a ...

Managing properties of classes within callbacks using TypeScript

I am currently working on the following task: class User { name: string; userService: UserService; //service responsible for fetching data from server successCallback(response: any) { this.name = string; } setUser() { ...

Creating a dynamic PHP calculator that provides instant results by taking input from an HTML form

For the sheer joy of coding in PHP, I decided to create a calculator. Take a look at the result: PHPTest Apologies for some German text within. Here's the Code: <?php $umsatz = $_POST['umsatz']; $varkost = $_POST['varkost& ...

Tailwind not properly filling the full width of the screen despite being a fixed element

Can someone assist me in achieving full-width for a fixed element in Tailwind? Check out the modal screenshot here: Modal Screenshot Please disregard the placeholder text as I am still in the testing phase. My React code: import { Dialog, Transition } f ...

Exploring and adding elements in a sophisticated array or object through recursive searching

After referring to this plunker https://plnkr.co/edit/CIGAA5BmiKU4hCMsOaIB?p=preview, I now require dynamic array operations. [ { title: 'Menu 1', id :1, hide : true, children: [], }, { title: 'Menu 2', hide : t ...

What is the best way to pass a function variable as a prop in a React JS component?

import React, { useState } from 'react' import Display from './components/Display'; const App = () => { const [input,setInput] = useState(""); const fetchData = async () => { const weatherAPI = await fet ...

What is the best way to eliminate unnecessary whitespaces from the className attribute in React using eslint and prettier?

I encountered an issue while working on React projects. It seems that prettier does not address the problem of unnecessary whitespaces in classNames. For instance: <img className='hidden lg:block ' src='./images/image-product-des ...

The "rest" variable is automatically assigned the type of "any" because it lacks a specified type and is used within its own initializer

Attempting to set up a private route using react router 4 and Typescript. Check out the code I'm working with: type CustomRouteProps<T> = T & { component: any, authRequired: boolean }; function PrivateRoute({ component: Component, authRequ ...

In NodeJS, inserting array objects into GraphQL is prohibited

Encountering an issue while trying to insert array objects. Below is the code snippet: GraphQL Schema type Member { _id: ID! member_id: Int! first_name: String! last_name: String username: String date: String } input MemberInput { member_i ...

Error: You are unable to process a payment for a customer without an active card on file. This issue occurs when attempting to complete a transaction

I am currently in the process of testing a payment system using Stripe, React, and Nodejs. On the front-end, I am utilizing createPaymentMethod() to send a post request with valid user information regarding products, quantity, user details, and address. H ...

Manipulate paths in JS/JQuery by dynamically adding parameters with an indefinite number of values

My JavaScript script relies on an AJAX call that adds a parameter to an HTML request, but I've encountered two issues. I'm struggling to find a straightforward method to retrieve the pathname with parameters. With pure JavaScript, location.path ...

Dividing and arranging dropdown list items into two columns using Bootstrap - An easy guide

How can I split a dropdown ul>li list into two columns using Bootstrap? I am attempting to divide the ul>li into two columns, with one aligning to the left and the other to the right. This is how I am currently doing it: <div class="btn-group" ...

What is the best way to modify an array's property in order to achieve the desired outcome when using json_encode?

Expected Result ['#ff0000','#4caf50','#4caf50','#4caf50','#00bcd4','#00bcd4','#4caf50','#4caf50'] The output I am receiving is as follows: ["'#ff0000','#4caf5 ...

What is the best way to incorporate an asp helper within a javascript script?

I am working on a JavaScript page layout and trying to incorporate CMS helpers into it. Despite successful rendering, the helpers are not functioning as expected (resulting in "NaN" instead of the desired text). How can I integrate helpers into a JavaScr ...

Excluding unnecessary TypeScript files in Angular 9

After upgrading from Angular 7 to Angular 9, I am encountering numerous errors like the one below. WARNING in C:\Users\DEV-SYS\Documents\GitHub\Angular-7\src\environments\environment.prod.ts is part of the Typ ...

Access both the main collection and its sub-collection in Firebase

I have been attempting to retrieve all data related to a collection and its subCollections within my Firestore database. The structure of the database is as follows: collection|->document|->subCollection|->document|-... |->field ...

Access the Android mobile application by using a JavaScript click event

I have been attempting to launch an installed android mobile application from an html page in the Chrome browser using a javascript or jQuery click function. While an anchor tag tap works perfectly and opens the installed app, I have encountered issues wh ...

Employ the fetch method to perform a get request along with a data object

In my current project, I am utilizing the Fetch API and I am looking to streamline the process by creating a function that can handle various parameters like method, url, and data in order to create the appropriate request for both GET and POST methods. I ...