Create a Animated Rotating Circle Menu Using Basic CSS

Share:



Create a Animated Rotating Circle Menu Using Basic CSS. 

In this article I 'll be talking about how we can arrange items around an item and creating a simple animation. At last we will get a similar design as above. You can check an live implementation here. I have implemented this on that website.
Firstly, you need to be familar with basic HTML, CSS, JavaScript and jQuery.

As we know that, CSS have not any features or any function that automatically places divisions or any elements in a circle or around a circle so we are using a simple technique of series of transformation. By rotation and translation and again rolling back the rotation we can get as our wish.


Here in the above images, diameters of outer and inner images  are 250px and 40px resp. Now, we have placed the inner image to the center of the outer image. Now, Moving the centered image to the desired loctation of the circle, here at the edge 45 deg clockwise. And by repeating this we can place as many images as we want (just changing the rotating angle).

Steps Performed:
  1. rotate the image @ 45 deg clock-wise i.e. rotate(45deg)
  2. translate (single axis) 125px i.e. translate(125px)
  3. rotate the image @ 45 deg anti-clock-wise i.e. rotate(-45deg)
 .deg{
    transform : rotate(45deg) ;
  }
    
 .deg2{
    transform : rotate(45deg) translate(125px);
  }
 .deg3{
    transform : rotate(45deg) translate(125px) rotate(-45deg);
  }

Now, as we know how to place the images in a circular form, we are going to arrange a certain number of images in that form.

Let us take a circle of size 26em (diameter).
CSS code for the circle: 
.circle-container{
   width: 26em;
   height: 26em;
   margin: 13em auto;
 }

We have here created a division of size 26em by 26em and made the div center horizontally. This division is just an imaginary area (not visible) to place our images.

Let us take the size of image to be 10em.
CSS code to position the image at the center:
.circle-item {
   list-style: none;
  }

.circle-item > li > img {
   display: block;
   position: absolute;
   top: 50%;
   left: 50%;
   width: 10em;
   height: 10em;
   border-radius: 50%;
   box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);
   border: solid 0px tomato;
   -webkit-transition: .15s;
   transition: .15s;
  }

.circle-item img:hover {
   box-shadow: 0 4px 8px 0 tomato;
}

Above code positions all of the images at the center of the imaginary division created above using the absolute position property.
Now, positioning all of the images at the correct places.

In this case we are arranging 7 items. Now, determine the difference between each items in angle so we can place at an equal distance. To do so,


Required difference = 360/7 = 51.54 deg ~ 51 deg (approx)
Translation size = 26em / 2 = 13em

Code to place all 7 images at correct places:
.circle-item > *:nth-of-type(1) {
   transform: rotate(0deg) translate(13em) rotate(0deg);
  }
.circle-item > *:nth-of-type(2) {
   transform: rotate(51deg) translate(13em) rotate(-51deg);
  }
.circle-item > *:nth-of-type(3) {
   transform: rotate(102deg) translate(13em) rotate(-102deg);
  }
.circle-item > *:nth-of-type(4) {
   transform: rotate(153deg) translate(13em) rotate(-153deg);
  }
.circle-item > *:nth-of-type(5) {
   transform: rotate(204deg) translate(13em) rotate(-204deg);
  }
.circle-item > *:nth-of-type(6) {
   transform: rotate(255deg) translate(13em) rotate(-255deg);
  }
.circle-item > *:nth-of-type(7) {
   transform: rotate(306deg) translate(13em) rotate(-306deg);
  }

We need 7 images so 7 individual placing is needed. Each code places the images at correct positions. It first rotates, then translates and again roll back the rotation. The process is explained above.The difference between the angle is approximately 51 deg.

HTML Code:   
   <div class = "circle-container">
     <ul class="circle-item">
      <li><img src="1.png"</li>
      <li><img src="2.png"</li>
      <li><img src="3.png"</li>
      <li><img src="4.png"</li>
      <li><img src="5.png"</li>
      <li><img src="6.png"</li>
      <li><img src="7.png"</li>
    </ul>
   </div>


In the above example, first an division is created of required size and then using absolute positioning property we position images at the center. Calculating the required value we transform those image to their expected position.

Now, There is space in between the images, we can place a big image over there by placing the following CSS code and another List element. I've placed at the last position in the sample file given at the end of the post..

CSS Code for the center image:

.circle-item > li:last-child > img{ // Increase the size of last element.
   width:15em;
   height:15em;
 }

.circle-item > *:nth-of-type(8) { // Position it using 'Hit and Trial Method'
   transform: rotate(228deg) translate(3.6em) rotate(-228deg);
}


This is the final product. CSS transform is not supported in old browsers and IE8. Also you can use
  -webkit-transform: rotate(90deg) translate(13em) rotate(+90deg);  /* Chrome, Opera 15+, Safari 3.1+ 
      -ms-transform: rotate(90deg) translate(13em) rotate(+90deg);  /* IE 9 
          transform: rotate(90deg) translate(13em) rotate(+90deg);  /* Firefox 16+, IE 10+, Opera 

You can also make this responsive by decereasing/increasing size on media queries. Now, Animating the circle by rotating. Inorder to rotate the circle we just need to update the rotating angle (adding 1 at an regular interval of time). 
Code To rotate the Circle just created:
$(function() {

    var deg = 0;
    var rotate = 1;
    var club_rotate = setInterval(club_rotate, 25);
    $('.circle-item > li').not(".circle-item > *:nth-of-type(8)").mouseenter(function() {
        rotate = 0
    });
    $('.circle-item > li').not(".circle-item > *:nth-of-type(8)").mouseleave(function() {
        rotate = 1
    });
    function club_rotate() {
        if (rotate == 0) {
            return
        }
        deg = get_deg(deg + 1);
        var deg0 = deg;
        var $data = $('.circle-item').children().not(".circle-item > *:nth-of-type(8)");
        var length = 13;
        if ($(window).width() <= 540) { // inorder to make it responsive, decreases size to 7em if window size is less than 570
            length = 7
        }
        $data.each(function() {
            $(this).css("-webkit-transform", "rotate(" + deg0 + "deg) translate(" + length + "em) rotate(-" + deg0 + "deg)").css("transform", "rotate(" + deg0 + "deg) translate(" + length + "em) rotate(-" + deg0 + "deg)");
            deg0 = get_deg(deg0 + 51)
        })
    }

    function get_deg(deg0) {
        if (deg0 > 360)
            return (deg0 - 360);
        else return deg0
    }
});

In the above code we call a function, in an regular interval, that autoupdate the rotating angle.
var club_rotate = setInterval(club_rotate, 25);
It calls the function club_rotate() at an interval of 25ms (every 25 milliseconds). 

  • club_rotate() - This function auto increase current angle by 1 and update in HTML. 
  • get_deg(deg0) - returns the corrected degree.

    $('.circle-item > li').not(".circle-item > *:nth-of-type(8)").mouseenter(function() {
        rotate = 0
    });
    $('.circle-item > li').not(".circle-item > *:nth-of-type(8)").mouseleave(function() {
        rotate = 1
    });

These codes resumes and pause the rotation on mouse leave and enter on the images except the center one
The JavaScript codes used here is just an ideal demonstration. Just to provide a concept.

No comments