React interview question - Detect overlapping circles
Tags: beginners, javascript, webdev, react
Published: 2022-12-09 09:54:28

---
title: React interview question - Detect overlapping circles
published: true
description: React interview question - Detect overlapping circles
tags: beginners, javascript, webdev, react
cover_image: https://i0.wp.com/learnersbucket.com/wp-content/uploads/2022/11/collision.jpg
canonical_url: https://learnersbucket.com/examples/interview/detect-overlapping-circles-in-react/
 
# cover_image: https://direct_url_to_image.jpg
# Use a ratio of 100:42 for best results.
# published_at: 2022-12-09 08:01 +0000
---

***
> I have written an Ebook that has 100 JavaScript, 20 React, & 2 Frontend system design questions. Get a [free preview](https://drive.google.com/file/d/1XWBItcsxD55S8GR2bWRkrxum0yNtfcym/view?usp=sharing) or [grab your copy for $10 or ₹599](https://learnersbucket.com/javascript-interview-guide-ebook/?epc_purge_single=1).
***

I have been collecting frontend interview questions since the last 4 years and have been writing about it on my blog [learnersbucket.com](https://learnersbucket.com)

Lately I have came across this interesting question that has been asked in an [Uber interview](https://leetcode.com/discuss/interview-question/1784074/Uber-or-Phone-or-Overlapping-circles-app-or-Reject) and I tried to solve it. 

## Question
Draw circles on the screen on the click and whenever two circles overlap change the color of the second circle.

- When a user clicks anywhere on the DOM, create a circle around it of a radius of 100px with red background.
- If two or more circles overlap, change the background of the later circle.

## Approach
Let us understand the logic of creating the circle first.

As we have to create the circle with a radius of 100px (200px diameter), rather than generating the circle on the click, we will store the coordinates of the position where the circle should be generated when the user clicks and then create circles out of these co-ordinates.

As all the circles will be in absolute position so that they can be freely placed on the screen, we will calculate the `top`, `bottom`, `left`, and `right` positions that will help in placement as well as detecting if two circles are colliding.

Get the [clientX](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/clientX) and [clientY](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/clientY) coordinates when the user clicks and align the circle around with a simple calculation so that it is placed in the center. Also before updating the state check if the current circle is overlapping with the existing circles then update the background color of the current.

```javascript
// helper function to gather configuration when user clicks
const draw = (e) => {
  // get the co-ordinates where user has clicked
  const { clientX, clientY } = e;

  // decide the position where circle will be created and placed
  // as the circle is of 100 radius (200 diameter), we are subtracting the values
  // so that circle is placed in the center
  // set the initial background color to red
  setElementsCoordinates((prevState) => {
    const current = {
      top: clientY - 100,
      left: clientX - 100,
      right: clientX - 100 + 200,
      bottom: clientY - 100 + 200,
      background: "red",
    };

    // before making the new entry
    // check with the exisitng circles
    for (let i = 0; i < prevState.length; i++) {
      // if the current circle is colliding with any existing
      // update the background color of the current
      if (elementsOverlap(current, prevState[i])) {
        current.background = getRandomColor();
        break;
      }
    }

    return [...prevState, current];
  });
};
```

Assign the event listener and draw the circle on the click.

```javascript
// assign the click event
  useEffect(() => {
    document.addEventListener("click", draw);
    return () => {
      document.removeEventListener("click", draw);
    };
  }, []);
```

Helper function to detect collision and generate random colors.

```javascript
// helper function to generate a random color
const getRandomColor = () => {
  const letters = "0123456789ABCDEF";
  let color = "#";
  for (let i = 0; i < 6; i++) {
    color += letters[Math.floor(Math.random() * 16)];
  }
  return color;
};

// helper function to detect if two elements are overlapping
const elementsOverlap = (rect1, rect2) => {
  const collide = !(
    rect1.top > rect2.bottom ||
    rect1.right < rect2.left ||
    rect1.bottom < rect2.top ||
    rect1.left > rect2.right
  );

  return collide;
};
```
Generate the circles from the coordinates which we have stored after the user has clicked. As the detection is done before making entry into the state, the circles are generated with different colors if they will be colliding.
```javascript
// circle element
const Circle = ({ top, left, background }) => {
  return (
    <div
      style={{
        position: "absolute",
        width: "200px",
        height: "200px",
        borderRadius: "50%",
        opacity: "0.5",
        background,
        top,
        left,
      }}
    ></div>
  );
};

return (
  <div>
    {/* render each circle */}
    {elementsCoordinates.map((e) => (
      <Circle {...e} key={e.top + e.left + e.right} />
    ))}
  </div>
);
```
Putting everything together.
```javascript
import { useEffect, useState } from "react";

// helper function to generate a random color
const getRandomColor = () => {
  const letters = "0123456789ABCDEF";
  let color = "#";
  for (let i = 0; i < 6; i++) {
    color += letters[Math.floor(Math.random() * 16)];
  }
  return color;
};

// helper function to detect if two elements are overlapping
const elementsOverlap = (rect1, rect2) => {
  const collide = !(
    rect1.top > rect2.bottom ||
    rect1.right < rect2.left ||
    rect1.bottom < rect2.top ||
    rect1.left > rect2.right
  );

  return collide;
};

const Example = () => {
  // store the configuration of each circle
  const [elementsCoordinates, setElementsCoordinates] = useState([]);

  // helper function to gather configuration when user clicks
  const draw = (e) => {
    // get the co-ordinates where user has clicked
    const { clientX, clientY } = e;

    // decide the position where circle will be created and placed
    // as the circle is of 100 radius (200 diameter), we are subtracting the values
    // so that circle is placed in the center
    // set the initial background color to red
    setElementsCoordinates((prevState) => {
      const current = {
        top: clientY - 100,
        left: clientX - 100,
        right: clientX - 100 + 200,
        bottom: clientY - 100 + 200,
        background: "red",
      };

      // before making the new entry
      // check with the exisitng circles
      for (let i = 0; i < prevState.length; i++) {
        // if the current circle is colliding with any existing
        // update the background color of the current
        if (elementsOverlap(current, prevState[i])) {
          current.background = getRandomColor();
          break;
        }
      }

      return [...prevState, current];
    });
  };

  // assign the click event
  useEffect(() => {
    document.addEventListener("click", draw);
    return () => {
      document.removeEventListener("click", draw);
    };
  }, []);

  // circle element
  const Circle = ({ top, left, background }) => {
    return (
      <div
        style={{
          position: "absolute",
          width: "200px",
          height: "200px",
          borderRadius: "50%",
          opacity: "0.5",
          background,
          top,
          left,
        }}
      ></div>
    );
  };

  return (
    <div>
      {/* render each circle */}
      {elementsCoordinates.map((e) => (
        <Circle {...e} key={e.top + e.left + e.right} />
      ))}
    </div>
  );
};

export default Example;
```

## Output
![Detect overlapping circles](https://i0.wp.com/learnersbucket.com/wp-content/uploads/2022/11/collision.jpg?w=1709&ssl=1)