Home > Blockchain >  Align images over a rounded rotating div
Align images over a rounded rotating div

Time:03-07

Considering a rounded(circle) parent div, I have to display on top of it several icons with the same width and distance between each other but they need to be parallel to the parent div. I tried to use rotate but needs to calculate the degrees dynamically. Also the rounded parent is spinning of 360 deg within few seconds.

My solution so far:

app.js

 <div> className='parent'
        {data.map((item, i) => (
          <div
            className='inner'
            key={i}
          >
            <img
              width={64}
              src={item.itemImg}
              alt={item.id}
              style={{ transformOrigin: 'center'; transform: rotate(-45deg) }}
            />
          </div>
        ))}
      </div>

css

div.parent {
  width: 450px;
  height: 450px;
  border: 1px solid #bbb;
  border-radius: 50%;
  display: flex;
  justify-content: space-between;
  position: relative;
  animation: spin 50s linear infinite;
}

What I have:

current

Is there a way to follow the shape of the parent ? If i hover over the element i still see a blue square

current2

Desired:

desired

CodePudding user response:

Here's a CSS way of doing it.

Each book div is a rectangle which sits with its bottom on the center of the circle and is 20% higher than the radius of the circle.

Each of these rectangles has a background image (in this case of a book) at the top.

The rectangle is rotated a number of degrees depending on what child number it is. This snippet uses 22.5 degrees as the base.

enter image description here

The whole thing is rotated so the books stay in the same relative position to the parent circle and their bases are parallel to a tangent to the circle.

Obviously you will want to change the dimensions, positoning etc to suit your use case.

.container {
  /* positioned in center of viewport just for demo */
  display: inline-block;
  width: 100vw;
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
}

.circle {
  --r: 20vmin;
  /* radius of the circle */
  --t: 8;
  /* total number of books */
  position: relative;
  --w: calc(var(--r) * 1.2);
  /* the top of the book is 20% out further than the edge of the circle */
  width: calc(2 * var(--w));
  height: calc(2 * var(--w));
  margin: 0;
  padding: 0;
  animation: rotate 10s linear infinite;
  animation-fill-mode: forwards;
}

@keyframes rotate {
  0% {
    transform: rotate(0);
  }
  100% {
    transform: rotate(360deg);
  }
}

.circle::before {
  content: '';
  width: calc(2 * var(--r));
  aspect-ratio: 1 / 1;
  border: 1px solid black;
  border-radius: 50%;
  position: absolute;
  top: calc(var(--r) * 0.2);
  left: calc(var(--r) * 0.2);
  display: inline-block;
  margin: 0;
  padding: 0;
}

.book {
  height: calc(var(--r) * 1.2);
  width: calc(var(--r) / 5);
  position: absolute;
  bottom: var(--w);
  left: calc(var(--w) - (0.5 * var(--r) / 5));
  transform-origin: center bottom;
  transform: rotate(calc(var(--n) * 22.5deg));
  position: absolute;
  background-image: url(https://i.stack.imgur.com/9XtVu.png);
  background-size: contain;
  background-position: 0 0;
  background-repeat: no-repeat;
  margin: 0;
  padding: 0;
}

.book:nth-child(1) {
  --n: 1;
}

.book:nth-child(2) {
  --n: 2;
}

.book:nth-child(3) {
  --n: 3;
}

.book:nth-child(4) {
  --n: 4;
}

.book:nth-child(5) {
  --n: 5;
}

.book:nth-child(6) {
  --n: 6;
}

.book:nth-child(7) {
  --n: 7;
}

.book:nth-child(8) {
  --n: 8;
}
<div >
  <div >
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
    <div ></div>
  </div>
</div>

  • Related