skip to Main Content

I am trying to place image inside nested borders line randomly.
Please help me! Thanks in advance

Expected result

How to place images in random position like above picture.

My code below:

  • HTML: I don’t care if the structure changes it just needs to work.
  • CSS: Please note this is just 1 method I have tried I have been sitting here for about 2 hours messing with this and couldn’t figure it out.
.first {
  border: 2px solid #D9DFE7;
  width: 385px;
  height: 385px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  margin-top: 40px;
  margin-left: 40px;
}

.img {
  width: 35px;
  height: 35px;
  border-radius: 50%;
  position: absolute;
  top: -1.1rem;
}

.second {
  border: 2px solid #D9DFE7;
  width: 301px;
  height: 301px;
  border-radius: 50%;
  margin: 2.5%;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
}

.imgSecond {
  width: 35px;
  height: 35px;
  border-radius: 50%;
  position: absolute;
  top: -1.1rem;
}

.third {
  border: 2px solid #D9DFE7;
  height: 215px;
  width: 215px;
  border-radius: 50%;
  margin: 15%;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
}

.imgThird {
  width: 35px;
  height: 35px;
  border-radius: 50%;
  position: absolute;
  top: -1.1rem;
}

.forth {
  border: 2px solid #D9DFE7;
  height: 133px;
  width: 133px;
  border-radius: 50%;
  margin: 2.5%;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
}

.imgForth {
  width: 35px;
  height: 35px;
  border-radius: 50%;
  position: absolute;
  top: -1.1rem;
}

.fifth {
  width: 49px;
  height: 49px;
  border: 2px solid #D9DFE7;
  border-radius: 50%;
  margin: 2.5%;
}
<div class="first">
  <img src="https://images.unsplash.com/photo-1683265379492-8179a1fff9c3?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=3498&q=80" class="img" />

  <div class="second">
    <img src="https://images.unsplash.com/photo-1683265379492-8179a1fff9c3?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=3498&q=80" class="imgSecond" />

    <div class="third">
      <img src="https://images.unsplash.com/photo-1683265379492-8179a1fff9c3?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=3498&q=80" class="imgThird" />

      <div class="forth">
        <img src="https://images.unsplash.com/photo-1683265379492-8179a1fff9c3?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=3498&q=80" class="imgForth" />
        <div class="fifth"></div>
      </div>
    </div>
  </div>
</div>

2

Answers


  1. To place them randomly on a circle you need to know the radius of the circle.
    Then you can use Math.random() to randomly choose an angle obviously from 0° to 360° and the use the following formulas to place your images.

    y = radius * sin(angle)
    x = radius * cos(angle)
    

    x and y and the x and y coordinates you need to place your images at which will be on the circle.

    Here an example using JavaScript canvas showing how the maths works. You can execute the snippet multiple times to see that indeed random points are being created.
    It is important to know that in a canvas the top-left corner has the coordinates (0, 0) which explains the calculation of the absolute values. Also you would need to know that sin(90°) = 1, sin(270°) = -1, cos(0°) = 1 and cos(180°) = -1 to make sense of the calculations.

    const canvas = document.getElementById("canvas");
    const context = canvas.getContext('2d');
    const centerX = canvas.width / 2;
    const centerY = canvas.height / 2;
    const radius = 45;
    
    function drawCircle(context, centerX, centerY, radius, lineWidth = 1){
      context.beginPath();
      context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
      context.lineWidth = lineWidth;
      context.strokeStyle = '#000';
      context.stroke();
    }
    
    drawCircle(context, centerX, centerY, radius);
    
    function randomAngle() {
      return Math.random() * 360;
    }
    
    function randomPointOnCircle(centerX, centerY, radius){
      const angle = randomAngle();
      const xRelativeCenter = radius * Math.sin(angle);
      const yRelativeCenter = radius * Math.cos(angle);
      const xAbsolute = centerX + xRelativeCenter;
      const yAbsolute = centerY - yRelativeCenter;
      return { x: xAbsolute, y: yAbsolute };
    }
    
    function drawRandomPointOnCircle(context, centerX, centerY, radius){
      const point = randomPointOnCircle(centerX, centerY, radius);
      console.log(`x = ${point.x}, y = ${point.y}`)
      drawCircle(context, point.x, point.y, 1, 2);
    }
    
    drawRandomPointOnCircle(context, centerX, centerY, radius);
    <canvas id="canvas" height="100px" width="100px" />

    If you want to do it in CSS:

    CSS has sin() and cos() functions, however without some pre-processor there is no random() function (as far as I know) so you would probably have to use Math.random() to generate the random numbers.

    Login or Signup to reply.
  2. We can define the images’ positions similar to polar coordinates: By rotating and offsetting from the center point.

    The offset places the images onto the rings. The rotation beforehand will place them along the rings.

    By randomizing the rotation, we randomly place the images along their rings.

    const rings = document.querySelectorAll(".ring");
    rings.forEach(ring => {
      const randomDegree = Math.random() * 360;
      ring.style.setProperty("--rotation", `${randomDegree}deg`);
    });
    #rings {
      padding: 16px;
      display: grid;
      place-items: center;
    }
    .ring {
      --size:;
      --rotation:;
      position: relative;
      grid-area: 1/1;
      border: 2px solid #d9dfe7;
      border-radius: 100%;
      aspect-ratio: 1/1;
      height: var(--size, auto);
    }
    
    .ring img {
      position: absolute;
      top: 50%;
      left: 50%;
      border: 1px solid blue;
      border-radius: 100%;
      aspect-ratio: 1/1;
      height: 35px;
      transform:
        translate(-50%, -50%) /*Center image on circle*/
        rotate(var(--rotation, 0deg)) /*Rotate around center relative to `--rotation`*/
        translateY(calc(var(--size, auto) * -0.5)) /*Offset onto circle along rotation*/
        rotate(calc(-1 * var(--rotation, 0deg))); /*Counter-rotate to have image upright*/
    }
    <div id="rings">
      <div class="ring" style="--size:385px">
        <img src="https://images.unsplash.com/photo-1683265379492-8179a1fff9c3">
      </div>
      <div class="ring" style="--size:301px">
        <img src="https://images.unsplash.com/photo-1683265379492-8179a1fff9c3">
      </div>
      <div class="ring" style="--size:215px">
        <img src="https://images.unsplash.com/photo-1683265379492-8179a1fff9c3">
      </div>
      <div class="ring" style="--size:133px">
        <img src="https://images.unsplash.com/photo-1683265379492-8179a1fff9c3">
      </div>
      <div class="ring" style="--size:49px">
        <img src="https://images.unsplash.com/photo-1683265379492-8179a1fff9c3">
      </div>
    </div>

    Note:

    • For an upright image, make sure to counter-rotate it after placement.
    • For an image centered on its line, make sure to translate it accordingly (by half its size).
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search