简体   繁体   中英

Rotate div clockwise or anticlockwise depending on current rotation

I have a set of buttons arranged in a circle, the button on the right hand side is the active button and emits a pulse animation. When another button is clicked, the containing div rotates so that the button you click is on the right, and becomes the active button

This is done using CSS transform: rotate(x); and transition

When I click the images below labelled 'C' I want the div to rotate clockwise, and 'A' anticlockwise. But this doesn't happen because of how I've done the CSS rotations, let's say the circle has rotated -300deg and then changes to a 180deg rotation, it will spin 'the long way round' instead of taking the shortest route.

在此输入图像描述

I need to rotate the div using JavaScript, then just add or subtract values from the rotation depending on what button I click. I've tried looking for ways to do this, but no luck so far.

Here's a fiddle showing my current progress

You can add data-rotate attributes to the buttons. Their values will be used add or subtract from the current rotate value.
Default HTML:

<div class="col-lg" id="wheel-container">
  <div class="wheel" data-state="1">
    <ul>
      <li><div><a class="btn active" data-icon="1"><div></div></a></div></li>
      <li><div><a class="btn" data-icon="2" data-rotate="-60"><div></div></a></div></li>
      <li><div><a class="btn" data-icon="3" data-rotate="-120"><div></div></a></div></li>
      <li><div><a class="btn" data-icon="4" data-rotate="180"><div></div></a></div></li>
      <li><div><a class="btn" data-icon="5" data-rotate="120"><div></div></a></div></li>
      <li><div><a class="btn" data-icon="6" data-rotate="60"><div></div></a></div></li>
    </ul>
  </div>
</div>

Remove this part of CSS. You no longer need it:

/* .wheel[data-state="1"] {
    transform: rotateZ(0deg);
}
.wheel[data-state="2"] {
    transform: rotateZ(-60deg);
}
.wheel[data-state="3"] {
    transform: rotateZ(-120deg);
}
.wheel[data-state="4"] {
    transform: rotateZ(180deg);
}
.wheel[data-state="5"] {
    transform: rotateZ(120deg);
}
.wheel[data-state="6"] {
    transform: rotateZ(60deg);
} */

Now, the jQuery code. It checks the data-rotate value of the clicked element to add/subtract the value from rotate variable. Then, it checks the position, and redistributes the values for each data-rotate appropriately.

var btns = $('.btn');
var rotate = 0;

$('.btn').on('click', function(e){
  e.preventDefault();
  if ($(this).hasClass('active')) {
    //Do nothing
  } else {

    var rotateAdd = Number($(this).data('rotate'));
    rotate += rotateAdd;
    $('.wheel').css({'transform' : 'rotate(' + rotate + 'deg)'});

    // get n value
    var icon = $(this).data('icon');
    var n = icon - 1;

    // loop to rearrange the values
    for (var i = 1; i < btns.length; i++) {
       n++;
       if (n === btns.length) {
          n = 0;
       }

      // apply rotate data again
       if (i == 1) {
         $(btns[n]).data('rotate', '-60');
       } else if (i == 2) {
         $(btns[n]).data('rotate', '-120');
       } else if (i == 3) {
         $(btns[n]).data('rotate', '180');        
       } else if (i == 4) {
         $(btns[n]).data('rotate', '120');     
       } else if (i == 5) {
         $(btns[n]).data('rotate', '60');
       }

    }

    // Hide other dropdowns
    $('.active').removeClass('active');
    // Open this dropdown
    $(this).addClass('active');
  }

});

working snippet :

 var btns = $('.btn'); var rotate = 0; $('.btn').on('click', function(e) { e.preventDefault(); if ($(this).hasClass('active')) { //Do nothing } else { var rotateAdd = Number($(this).data('rotate')); rotate += rotateAdd; $('.wheel').css({ 'transform': 'rotate(' + rotate + 'deg)' }); // get n value var icon = $(this).data('icon'); var n = icon - 1; // loop to rearrange the values for (var i = 1; i < btns.length; i++) { n++; if (n === btns.length) { n = 0; } // apply rotate data again if (i == 1) { $(btns[n]).data('rotate', '-60'); } else if (i == 2) { $(btns[n]).data('rotate', '-120'); } else if (i == 3) { $(btns[n]).data('rotate', '180'); } else if (i == 4) { $(btns[n]).data('rotate', '120'); } else if (i == 5) { $(btns[n]).data('rotate', '60'); } } // Hide other dropdowns $('.active').removeClass('active'); // Open this dropdown $(this).addClass('active'); } }); 
 #wheel-container { flex: 1 1 100%; max-width: 100%; position: relative; } .wheel { width: calc(50vw - 1.875rem); position: relative; margin: auto; } .wheel ul { list-style: none; padding: 0; margin: 0; width: 100%; padding-top: 100%; position: relative; } .wheel ul li { padding: 0; margin: 0; width: 50%; height: 50%; position: absolute; left: 50%; top: 50%; transform-origin: 0 50%; } .wheel ul li>div { width: 100%; height: 100%; position: relative; } .wheel ul li [data-icon] { width: 50%; height: 50%; border-radius: 50%; position: absolute; right: 0; top: 50%; transform-origin: 50% 50%; transform: translateY(-50%); cursor: pointer; padding: 0; } .wheel ul li [data-icon]>div { width: 100%; height: 100%; position: relative; overflow: visible; z-index: -10; } .wheel ul li [data-icon]>div::after { content: ''; position: absolute; top: 0; left: 0; bottom: 0; right: 0; border-radius: 50%; } .wheel ul li [data-icon].active>div::before { content: ''; position: absolute; width: 100%; height: 100%; top: 50%; left: 50%; background: rgba(0, 173, 239, 0.5); transform: translate(-50%, -50%); animation-name: pulse; animation-timing-function: ease-in-out; animation-iteration-count: infinite; animation-duration: 3s; animation-direction: alternate; border-radius: 50%; } @keyframes pulse { 0% { width: 100%; height: 100%; opacity: 0; } 50% { width: calc(100% + 1rem); height: calc(100% + 1rem); opacity: 1; } 100% { width: 100%; height: 100%; opacity: 0; } } .wheel ul li:nth-child(1) { transform: translateY(-50%); } .wheel ul li:nth-child(2) { transform: translateY(-50%)rotateZ(60deg); } .wheel ul li:nth-child(3) { transform: translateY(-50%)rotateZ(120deg); } .wheel ul li:nth-child(4) { transform: translateY(-50%)rotateZ(180deg); } .wheel ul li:nth-child(5) { transform: translateY(-50%)rotateZ(240deg); } .wheel ul li:nth-child(6) { transform: translateY(-50%)rotateZ(300deg); } .wheel[data-state] { transition: transform 1s ease-in-out; transform-origin: 50% 50%; } .wheel[data-state="1"] { transform: rotateZ(0deg); } .wheel[data-state="2"] { transform: rotateZ(-60deg); } .wheel[data-state="3"] { transform: rotateZ(-120deg); } .wheel[data-state="4"] { transform: rotateZ(180deg); } .wheel[data-state="5"] { transform: rotateZ(120deg); } .wheel[data-state="6"] { transform: rotateZ(60deg); } .wheel ul li:nth-child(1) [data-icon]>div::after { background: url('https://www.fillmurray.com/200/200') 0 0 / contain no-repeat; } .wheel ul li:nth-child(2) [data-icon]>div::after { background: url('https://www.fillmurray.com/200/200') 0 0 / contain no-repeat; transform: rotateZ(-60deg); } .wheel ul li:nth-child(3) [data-icon]>div::after { background: url('https://www.fillmurray.com/200/200') 0 0 / contain no-repeat; transform: rotateZ(-120deg); } .wheel ul li:nth-child(4) [data-icon]>div::after { background: url('https://www.fillmurray.com/200/200') 0 0 / contain no-repeat; transform: rotateZ(-180deg); } .wheel ul li:nth-child(5) [data-icon]>div::after { background: url('https://www.fillmurray.com/200/200') 0 0 / contain no-repeat; transform: rotateZ(-240deg); } .wheel ul li:nth-child(6) [data-icon]>div::after { background: url('https://www.fillmurray.com/200/200') 0 0 / contain no-repeat; transform: rotateZ(-300deg); } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div class="col-lg" id="wheel-container"> <div class="wheel" data-state="1"> <ul> <li> <div> <a class="btn active" data-icon="1"> <div></div> </a> </div> </li> <li> <div> <a class="btn" data-icon="2" data-rotate="-60"> <div></div> </a> </div> </li> <li> <div> <a class="btn" data-icon="3" data-rotate="-120"> <div></div> </a> </div> </li> <li> <div> <a class="btn" data-icon="4" data-rotate="180"> <div></div> </a> </div> </li> <li> <div> <a class="btn" data-icon="5" data-rotate="120"> <div></div> </a> </div> </li> <li> <div> <a class="btn" data-icon="6" data-rotate="60"> <div></div> </a> </div> </li> </ul> </div> </div> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM