Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rotate objects around circle using CSS?

I'm attempting to have three objects rotating around a circle. So far I've been able to get one object to spin around the circle. I am unable to get more than one without messing up the code. Could anyone advise on the best way to accomplish this? Here is part of the code and a Fiddle. Thanks!

Here is the Demo

.outCircle {
  width: 200px;
  height: 200px;
  background-color: lightblue;
  left: 270px;
  position: absolute;
  top: 50px;
  -moz-border-radius: 100px;
  -webkit-border-radius: 100px;
  border-radius: 100px;
}
.rotate {
  width: 100%;
  height: 100%;
  -webkit-animation: circle 10s infinite linear;
}
.counterrotate {
  width: 50px;
  height: 50px;
  -webkit-animation: ccircle 10s infinite linear;
}
.inner {
  width: 100px;
  height: 100px;
  background: red;
  -moz-border-radius: 50px;
  -webkit-border-radius: 50px;
  border-radius: 100px;
  position: absolute;
  left: 0px;
  top: 0px;
  background-color: red;
  display: block;
}
@-webkit-keyframes circle {
  from {
    -webkit-transform: rotateZ(0deg)
  }
  to {
    -webkit-transform: rotateZ(360deg)
  }
}
@-webkit-keyframes ccircle {
  from {
    -webkit-transform: rotateZ(360deg)
  }
  to {
    -webkit-transform: rotateZ(0deg)
  }
}
<div class="outCircle">
  <div class="rotate">
    <div class="counterrotate">
      <div class="inner">hello
      </div>
    </div>
  </div>
</div>
like image 804
AndrewLeonardi Avatar asked Aug 18 '16 14:08

AndrewLeonardi


People also ask

How do I rotate an item in CSS?

CSS rotate() Let's take a look at the syntax for the rotate() function: transform: rotate(angle); The value “angle” represents the number of degrees the element should rotate. You can specify a rotate that is clockwise using a positive degree number (i.e. 45).

How do I round a shape in CSS?

To create a circle we can set the border-radius on the element. This will create curved corners on the element. If we set it to 50% it will create a circle. If you set a different width and height we will get an oval instead.


2 Answers

Here is a more generic idea with less of where you don't need JS and you only need to apply an animation to the item (not the container). The trick is to make all the elements at the same position and using the same animationthen with the delay we can have the needed result:

#container {
  width: 200px;
  height: 200px;
  margin: 40px auto;
  border: 1px solid #000;
  display:grid;
  grid-template-columns:30px;
  grid-template-rows:30px;
  place-content: center;
  border-radius: 50%;
}
.item {
  grid-area:1/1;
  line-height: 30px;
  text-align: center;
  border-radius: 50%;
  background: #f00;
  animation: spin 12s var(--d,0s) linear infinite; /* duration = 12s, numbor of item = 6 so a delay of 12/6 = 2s */
  transform:rotate(0) translate(100px) rotate(0);
}
@keyframes spin {
  100% {
    transform:rotate(1turn) translate(100px) rotate(-1turn);
  }
}
<div id="container">
  <div class="item" style="--d:0s">1</div>
  <div class="item" style="--d:-2s">2</div>
  <div class="item" style="--d:-4s">3</div>
  <div class="item" style="--d:-6s">4</div>
  <div class="item" style="--d:-8s">5</div>
  <div class="item" style="--d:-10s">6</div>
</div>

We can easily scale to any number using some CSS variables:

#container {
  --n:7;   /* number of item */
  --d:12s; /* duration */

  width: 200px;
  height: 200px;
  margin: 40px auto;
  border: 1px solid #000;
  display:grid;
  grid-template-columns:30px;
  grid-template-rows:30px;
  place-content: center;
  border-radius: 50%;
}
.item {
  grid-area:1/1;
  line-height: 30px;
  text-align: center;
  border-radius: 50%;
  background: #f00;
  animation: spin var(--d) linear infinite; 
  transform:rotate(0) translate(100px) rotate(0);
}
@keyframes spin {
  100% {
    transform:rotate(1turn) translate(100px) rotate(-1turn);
  }
}

.item:nth-child(1) {animation-delay:calc(-0*var(--d)/var(--n))}
.item:nth-child(2) {animation-delay:calc(-1*var(--d)/var(--n))}
.item:nth-child(3) {animation-delay:calc(-2*var(--d)/var(--n))}
.item:nth-child(4) {animation-delay:calc(-3*var(--d)/var(--n))}
.item:nth-child(5) {animation-delay:calc(-4*var(--d)/var(--n))}
.item:nth-child(6) {animation-delay:calc(-5*var(--d)/var(--n))}
.item:nth-child(7) {animation-delay:calc(-6*var(--d)/var(--n))}
.item:nth-child(8) {animation-delay:calc(-7*var(--d)/var(--n))}
.item:nth-child(9) {animation-delay:calc(-8*var(--d)/var(--n))}
/*.item:nth-child(N) {animation-delay:calc(-(N - 1)*var(--d)/var(--n))}*/
<div id="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
  <div class="item">4</div>
  <div class="item">5</div>
  <div class="item">6</div>
  <div class="item">7</div>
</div>

<div id="container" style="--n:5;--d:5s">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
  <div class="item">4</div>
  <div class="item">5</div>
</div>

<div id="container" style="--n:9">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
  <div class="item">4</div>
  <div class="item">5</div>
  <div class="item">6</div>
  <div class="item">7</div>
  <div class="item">8</div>
  <div class="item">9</div>
</div>
like image 115
Temani Afif Avatar answered Oct 09 '22 00:10

Temani Afif


Jquery solution which works for any number of outer items.

Jquery shamelessly stolen from ThiefMaster♦ and their answer at this Q & A

var radius = 100; // adjust to move out items in and out 
var fields = $('.item'),
  container = $('#container'),
  width = container.width(),
  height = container.height();
var angle = 0,
  step = (2 * Math.PI) / fields.length;
fields.each(function() {
  var x = Math.round(width / 2 + radius * Math.cos(angle) - $(this).width() / 2);
  var y = Math.round(height / 2 + radius * Math.sin(angle) - $(this).height() / 2);
  if (window.console) {
    console.log($(this).text(), x, y);
  }
  $(this).css({
    left: x + 'px',
    top: y + 'px'
  });
  angle += step;
});
body {
  padding: 2em;
}
#container {
  width: 200px;
  height: 200px;
  margin: 10px auto;
  border: 1px solid #000;
  position: relative;
  border-radius: 50%;
  animation: spin 10s linear infinite;
}
.item {
  width: 30px;
  height: 30px;
  line-height: 30px;
  text-align: center;
  border-radius: 50%;
  position: absolute;
  background: #f00;
  animation: spin 10s linear infinite reverse;
}
@keyframes spin {
  100% {
    transform: rotate(1turn);
  }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
  <div class="item">4</div>
  <div class="item">5</div>
  <div class="item">6</div>
</div>
like image 40
Paulie_D Avatar answered Oct 08 '22 22:10

Paulie_D