Non
Non

Reputation: 8589

How to set an animation to have elements moving around a circle?

I am trying to achieve what you see in the picture:

enter image description here

The picture is here in case it is block for you: https://i.sstatic.net/YYg4J.jpg

There you may see only one icon but actually are 4 icons, the picture represent the path that the icons should take.

I have create an snippet or here is a Codepen

var outerBox = $('.eight-box'),
    boxHeight = $(outerBox).height(),
    boxWidth = $(outerBox).width();
function changeNumbers() {
  var pos1 = $('.pos-1'),
      pos2 = $('.pos-2'),
      pos3 = $('.pos-3'),
      pos4 = $('.pos-4');

  $('.col-1').addClass('pos-1');
  $('.col-1').removeClass('pos-4')
  $('.col-2').addClass('pos-2');
  $('.col-2').removeClass('pos-4')
  $('.col-3').addClass('pos-3');
  $('.col-3').removeClass('pos-4')
  
};
// var refreshId = setInterval(changeNumbers, 1500);
changeNumbers();
.eight-box {
	position: relative;
	display: block;
	margin: 1em auto;
	width: 16em;
  height: 16em;
  font-family: sans-serif;
  font-size: 20px;
  border: 1px solid;
  border-radius: 50%;
}
.fig-8 {
	display: block;
	position: absolute;
	color: #fff;
	width: 2em;
  height: 2em;
  line-height: 2;
  text-align: center;
  font-weight: bold;
  font-smoothing: antialiased;
	transition: all .5s linear;
  overflow: hidden;
  z-index: 5;
}

.col-1 {
	background: #1abc9c;
}
.col-2 {
	background: #9b59b6;
}
.col-3 {
	background: #27ae60;
}
.col-4 {
	background: #2c3e50;
}

.pos-1 {
	top: 30%;
	left: 93.75%;
}
.pos-2 {
	top: 66.25%;
	left: 88.75%;
}
.pos-3 {
	top: 72.92%;
	right: 83.125%;
}
.pos-4 {
	top: 19.58%;
	right: 88.75%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="eight-box">
  <div class="fig-8 col-1 pos-4">1</div>
  <div class="fig-8 col-2 pos-4">2</div>
  <div class="fig-8 col-3 pos-4">3</div>
  <div class="fig-8 col-4 pos-4">4</div>
</div>

This is the description of what I should achieve:

1 - All the icons must be in the same place when the page loads, which is the place where you may see the icon with the number 4.

2 - Then, every icon should start its path around the circle, getting stick to its regular state/position. I mean: Icon with number 3 starts its track and then once it reach its position it should stick there and the same with the other icons.

For now, if you see the code snippet I did, the icons are doing some animation by getting to its original position after the page loads, but I am unable to achieve what I need which is triggering the icons to get back to its original position by going around the circle.

TL;DR: The icons starts from the position with the icon number 4 on page load, and then the icons should get back to its original position by moving around the circle, from left to right.

For example: Icon 4 should stay where it is. Icon 3 should move downwards some pixels around the circle. And so on.

So they should all come in from the left moving towards the right (like follow the leader) and end in the position they are in in the picture or codepen/codespnippet.

Any suggestions?

Upvotes: 3

Views: 465

Answers (1)

G-Cyrillus
G-Cyrillus

Reputation: 105853

You may inspire yourself from these 2 pens using animation and transform:rotate().

  • This one with inputs element to interact with: click 1 to show 2, 3, 4, 5 . Then click 2, then 3, ... to see them going around the circle. After the first click you can also control them with the arrow keys. (The code snippet is a little bit more optimized than the pen, code-wise.)

input[name="group"] {position:absolute; right:100vw}

.circle {
  position: relative;
  width: 50vh;
  height: 50vh;
  margin: 25vh auto;
  border: solid 1px;
  border-radius: 100%;
}

.rotate, .rotate label {transition:1s;}

.rotate {
  display: flex;
  align-items: flex-end;
  position: absolute;
  top: 50%;
  left: 50%;
  width: 10vh;
  height: 60%;
  margin-left: -5vh;
  transform-origin: 5vh 0;
}
.rotate:first-child {z-index:1;}

.rotate label {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 10vh;
  height: 10vh;
  border: solid 1px;
  border-radius: 100%;
  background: #0095FF;
  cursor:pointer
}

/* one */
#one:checked ~ .circle #a {transform:rotate(120deg);}
#one:checked ~ .circle #a label {transform:rotate(-120deg);}

#one:checked ~ .circle #b {transform:rotate(90deg);}
#one:checked ~ .circle #b label {transform:rotate(-90deg);}

#one:checked ~ .circle #c {transform:rotate(60deg);}
#one:checked ~ .circle #c label {transform:rotate(-60deg);}

#one:checked ~ .circle #d {transform:rotate(30deg);}
#one:checked ~ .circle #d label {transform:rotate(-30deg);}

#one:checked ~ .circle #e {transform:rotate(0deg);}
#one:checked ~ .circle #e label {transform:rotate(-0deg);}

/* two */
#two:checked ~ .circle #b {transform:rotate(120deg);}
#two:checked ~ .circle #b label {transform:rotate(-120deg);}

#two:checked ~ .circle #c {transform:rotate(90deg);}
#two:checked ~ .circle #c label {transform:rotate(-90deg);}

#two:checked ~ .circle #d {transform:rotate(60deg);}
#two:checked ~ .circle #d label {transform:rotate(-60deg);}

#two:checked ~ .circle #e {transform:rotate(30deg);}
#two:checked ~ .circle #e label {transform:rotate(-30deg);}

#two:checked ~ .circle #a {transform:rotate(360deg);}
#two:checked ~ .circle #a label {transform:rotate(-0deg);}

/* three */
#three:checked ~ .circle #c {transform:rotate(120deg);}
#three:checked ~ .circle #c label {transform:rotate(-120deg);}

#three:checked ~ .circle #d {transform:rotate(90deg);}
#three:checked ~ .circle #d label {transform:rotate(-90deg);}

#three:checked ~ .circle #e {transform:rotate(60deg);}
#three:checked ~ .circle #e label {transform:rotate(-60deg);}

#three:checked ~ .circle #a {transform:rotate(390deg);}
#three:checked ~ .circle #a label {transform:rotate(-30deg);}

#three:checked ~ .circle #b {transform:rotate(360deg);}
#three:checked ~ .circle #b label {transform:rotate(-0deg);}

/* four */
#four:checked ~ .circle #d {transform:rotate(120deg);}
#four:checked ~ .circle #d label {transform:rotate(-120deg);}

#four:checked ~ .circle #e {transform:rotate(90deg);}
#four:checked ~ .circle #e label {transform:rotate(-90deg);}

#four:checked ~ .circle #a {transform:rotate(420deg);}
#four:checked ~ .circle #a label {transform:rotate(-60deg);}

#four:checked ~ .circle #b {transform:rotate(390deg);}
#four:checked ~ .circle #b label {transform:rotate(-30deg);}

#four:checked ~ .circle #c {transform:rotate(360deg);}
#four:checked ~ .circle #c label {transform:rotate(-0deg);}

/* five */
#five:checked ~ .circle #e {transform:rotate(120deg);}
#five:checked ~ .circle #e label {transform:rotate(-120deg);}

#five:checked ~ .circle #a {transform:rotate(450deg);}
#five:checked ~ .circle #a label {transform:rotate(-90deg);}

#five:checked ~ .circle #b {transform:rotate(420deg);}
#five:checked ~ .circle #b label {transform:rotate(-60deg);}

#five:checked ~ .circle #c {transform:rotate(390deg);}
#five:checked ~ .circle #c label {transform:rotate(-30deg);}

#five:checked ~ .circle #d {transform:rotate(360deg);}
#five:checked ~ .circle #d label {transform:rotate(-0deg);}
<input id="one" type="radio"  name="group" />
<input id="two" type="radio" name="group" />
<input id="three" type="radio" name="group" />
<input id="four" type="radio" name="group" />
<input id="five" type="radio" name="group" />

<div class="circle">
  <div id="a" class="rotate"><label for="one">1</label></div>
  <div id="b" class="rotate"><label for="two">2</label></div>
  <div id="c" class="rotate"><label for="three">3</label></div>
  <div id="d" class="rotate"><label for="four">4</label></div>
  <div id="e" class="rotate"><label for="five">5</label></div>
</div>

  • And this other one with a demo animation running:

.circle {
  height: 50vh;
  width: 50vh;
  border-radius: 100%;
  border: solid;
  margin: 25vh auto;
  position: relative;
}

.rotate {
  height: 60%;
  position: absolute;
  top: 50%;
  left: 50%;
  width: 10vh;
  margin-left: -5vh;
  display: flex;
  align-items: flex-end;
}

.rotate div {
  border-radius: 100%;
  border: solid;
  height: 10vh;
  width: 10vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background: white
}

#a {
  transform-origin: 5vh 0;
  transform: rotate(120deg);
  animation: roundcircle 5s infinite;
}

#a  div {
  animation: roundcirclediv 5s infinite;
}

#b {
  transform-origin: 5vh 0;
  transform: rotate(90deg);
  animation: roundcircle 5s -1s infinite;
}

#b div {
  transform: rotate(-90deg);
  animation: roundcirclediv 5s -1s infinite;
}

#c {
  transform-origin: 5vh 0;
  transform: rotate(60deg);
  animation: roundcircle 5s -2s infinite;
}

#c div {
  transform: rotate(-60deg);
  animation: roundcirclediv 5s -2s infinite;
}

#d {
  transform-origin: 5vh 0;
  transform: rotate(30deg);
  animation: roundcircle 5s -3s infinite;
}

#d div {
  transform: rotate(-30deg);
  animation: roundcirclediv 5s -3s infinite;
}

#e {
  transform-origin: 5vh 0;
  transform: rotate(0deg);
  animation: roundcircle 5s -4s infinite;
}

#e div {
  transform: rotate(-0deg);
  animation: roundcirclediv 5s -4s infinite;
}

@keyframes roundcircle {
  0% {
    transform: rotate(120deg);
  }
  20% {
    transform: rotate(360deg)
  }
  40% {
    transform: rotate(390deg)
  }
  60% {
    transform: rotate(420deg)
  }
  80% {
    transform: rotate(450deg)
  }
  100% {
    transform: rotate(480deg);
  }
}

@keyframes roundcirclediv {
  0% {
    transform: rotate(-120deg);
  }
  20% {
    transform: rotate(-360deg)
  }
  40% {
    transform: rotate(-390deg)
  }
  60% {
    transform: rotate(-420deg)
  }
  80% {
    transform: rotate(-450deg)
  }
  100% {
    transform: rotate(-480deg);
  }
}
<div class="circle">
  <div id="a" class="rotate">
    <div>1</div>
  </div>
  <div id="b" class="rotate">
    <div>2</div>
  </div>
  <div id="c" class="rotate">
    <div>3</div>
  </div>
  <div id="d" class="rotate">
    <div>4</div>
  </div>
  <div id="e" class="rotate">
    <div>5</div>
  </div>
</div>


  • And if you're having a hard time understanding how this works, check out this one, to see behind the magic curtain:

input[name="group"] {position:absolute; right:100vw}

.circle {
  height: 50vh;
  width: 50vh;
  border-radius: 100%;
  border: solid 1px;
  margin: 25vh auto;
  position: relative;
}

.rotate {
  height: 60%;
  position: absolute;
  top: 50%;
  left: 50%;
  width: 10vh;
  margin-left: -5vh;
  display: flex;
  align-items: flex-end;
}

.rotate div {
  border-radius: 100%;
  border: solid 1px;
  height: 10vh;
  width: 10vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #0095FF;
}

#a, #a div, #b , #b div, #c, #c div, #d, #d div, #e, #e div {transition:1s; box-shadow:0 0 5px}
#a, #b, #c, #d, #e {transform-origin:5vh 0;}
#a {z-index:1;}
label {cursor:pointer}

/* one */

#one:checked ~ .circle #a {transform:rotate(120deg);}
#one:checked ~ .circle #a div {transform:rotate(-120deg);}

#one:checked ~ .circle #b {transform:rotate(90deg);}
#one:checked ~ .circle #b div {transform:rotate(-90deg);}

#one:checked ~ .circle #c {transform:rotate(60deg);}
#one:checked ~ .circle #c div {transform:rotate(-60deg);}

#one:checked ~ .circle #d {transform:rotate(30deg);}
#one:checked ~ .circle #d div {transform:rotate(-30deg);}

#one:checked ~ .circle #e {transform:rotate(0deg);}
#one:checked ~ .circle #e div {transform:rotate(-0deg);}

/* two */

#two:checked ~ .circle #b {transform:rotate(120deg);}
#two:checked ~ .circle #b div {transform:rotate(-120deg);}

#two:checked ~ .circle #c {transform:rotate(90deg);}
#two:checked ~ .circle #c div {transform:rotate(-90deg);}

#two:checked ~ .circle #d {transform:rotate(60deg);}
#two:checked ~ .circle #d div {transform:rotate(-60deg);}

#two:checked ~ .circle #e {transform:rotate(30deg);}
#two:checked ~ .circle #e div {transform:rotate(-30deg);}

#two:checked ~ .circle #a {transform:rotate(360deg);}
#two:checked ~ .circle #a div {transform:rotate(-0deg);}

/* three */

#three:checked ~ .circle #c {transform:rotate(120deg);}
#three:checked ~ .circle #c div {transform:rotate(-120deg);}

#three:checked ~ .circle #d {transform:rotate(90deg);}
#three:checked ~ .circle #d div {transform:rotate(-90deg);}

#three:checked ~ .circle #e {transform:rotate(60deg);}
#three:checked ~ .circle #e div {transform:rotate(-60deg);}

#three:checked ~ .circle #a {transform:rotate(390deg);}
#three:checked ~ .circle #a div {transform:rotate(-30deg);}

#three:checked ~ .circle #b {transform:rotate(360deg);}
#three:checked ~ .circle #b div {transform:rotate(-0deg);}

/* four */

#four:checked ~ .circle #d {transform:rotate(120deg);}
#four:checked ~ .circle #d div {transform:rotate(-120deg);}

#four:checked ~ .circle #e {transform:rotate(90deg);}
#four:checked ~ .circle #e div {transform:rotate(-90deg);}

#four:checked ~ .circle #a {transform:rotate(420deg);}
#four:checked ~ .circle #a div {transform:rotate(-60deg);}

#four:checked ~ .circle #b {transform:rotate(390deg);}
#four:checked ~ .circle #b div {transform:rotate(-30deg);}

#four:checked ~ .circle #c {transform:rotate(360deg);}
#four:checked ~ .circle #c div {transform:rotate(-0deg);}

/* five */

#five:checked ~ .circle #e {transform:rotate(120deg);}
#five:checked ~ .circle #e div {transform:rotate(-120deg);}

#five:checked ~ .circle #a {transform:rotate(450deg);}
#five:checked ~ .circle #a div {transform:rotate(-90deg);}

#five:checked ~ .circle #b {transform:rotate(420deg);}
#five:checked ~ .circle #b div {transform:rotate(-60deg);}

#five:checked ~ .circle #c {transform:rotate(390deg);}
#five:checked ~ .circle #c div {transform:rotate(-30deg);}

#five:checked ~ .circle #d {transform:rotate(360deg);}
#five:checked ~ .circle #d div {transform:rotate(-0deg);}
<input id="one" type="radio"  name="group" />
<input id="two" type="radio" name="group" />
<input id="three" type="radio" name="group" />
<input id="four" type="radio" name="group" />
<input id="five" type="radio" name="group" />

<div class="circle">
  <div id="a" class="rotate">
    <div><label for="one">1</label></div>
  </div>
  <div id="b" class="rotate">
    <div><label for="two">2</label></div>
  </div>
  <div id="c" class="rotate">
    <div><label for="three">3</div>
  </div>
  <div id="d" class="rotate">
    <div><label for="four">4</label></div>
  </div>
  <div id="e" class="rotate">
    <div><label for="five">5</label></div>
  </div>
</div>

Upvotes: 1

Related Questions