JSFiddle - React, Tailwind, and code Playground

by Steve Ayers

HTML

<div id="marker" class="marker">
</div>

<button>Spin</button>

CSS

.marker {
  width: 100px;
  height: 200px;
  margin: 50px;
  background: blue;
  border-top: 5px solid #01c01c;
  transition: all .3s linear;
}

JavaScript

//const rotes = [0, -55, 90, 141, 173, 229.28, 47, 175, -11, -55, 266];
const rotes = [90, 185, -90, 270, -90];
let index = -1;
let prevIndex = -1;
const marker = document.getElementById('marker');
document.querySelectorAll('button').forEach((node) => {
   node.addEventListener('click', () => {
      currentHeading = getRotationDegrees(marker);
      if (index === rotes.length - 1) {
        index = 0;
        prevIndex = rotes.length - 1;
      } else {
        prevIndex = index;
        index += 1;
      }

      let newHeading = rotes[index];
      let prevHeading = rotes[prevIndex];
      let adjustedNewHeading;
      let finalNewHeading;
      
      if (newHeading < 0 || newHeading > 180) {
         if (newHeading < 0) {
            newHeading = Math.abs(newHeading);
         }
         adjustedNewHeading = newHeading - 360;

         const prevNewDiff = newHeading - prevHeading;
         const prevAdjNewDiff = adjustedNewHeading - prevHeading;
         if (Math.abs(prevNewDiff) < Math.abs(prevAdjNewDiff)) {
            finalNewHeading = newHeading;
         } else {
            finalNewHeading = adjustedNewHeading;
         }
         console.log('going with ', finalNewHeading)
      } else {
         finalNewHeading = newHeading;
      }
      marker.style.transform = 'rotate(' + finalNewHeading + 'deg)';
   });
});

function getRotationDegrees(element) {
    // get the computed style object for the element
    var style = window.getComputedStyle(element);
    // this string will be in the form 'matrix(a, b, c, d, tx, ty)'
    var transformString = style['-webkit-transform']
                       || style['-moz-transform']
                       || style['transform'] ;
    if (!transformString || transformString == 'none')
        return 0;
    var splits = transformString.split(',');
    // parse the string to get a and b
    var parenLoc = splits[0].indexOf('(');
    var a = parseFloat(splits[0].substr(parenLoc+1));
    var b = parseFloat(splits[1]);
 ...