Rotate element with mouse

by kapantzak

HTML

<div class="circle-holder">
  <div class="menu-mark"></div>
  <div class="menu-mark"></div>
  <div class="menu-mark"></div>
  <div class="menu-mark"></div>
  <div class="menu-mark"></div>
  <div class="circle">  
    <div class="marker"></div>
  </div>  
</div>

CSS

.circle-holder,
.circle {
  width: 200px;
  height: 200px;
  margin: 0 auto;
  margin-top: 100px;
  position: relative;
  border-radius: 50%;
  box-sizing: border-box;
}

.circle {
  border: 1px solid #d8d8d8;
  box-shadow: 0 0 15px 0 rgba(0, 0, 0, 0.5);
  background-color: #fff;
}

.marker {
  width: 20px;
  height: 20px;
  position: absolute;
  top: 5px;
  left: 50%;
  margin-left: -10px;
  border-radius: 50%;
  box-shadow: inset 0 0 10px 0 rgba(0, 0, 0, 0.5);
  cursor: grab;
}

.menu-mark {
  width: 2px;
  height: 120px;
  position: absolute;
  top: -20px;
  left: 50%;
  margin-left: -1px;
  background-color: #777;
  transform-origin: bottom center;
}

JavaScript

const crl = $('.circle');
const mrk = $('.marker');
const offset = crl.offset();
let mouseDown = false;

function mouse(evt) {
  if (mouseDown) {
    const center_x = (offset.left) + (crl.width() / 2);
    const center_y = (offset.top) + (crl.height() / 2);
    const mouse_x = evt.pageX;
    const mouse_y = evt.pageY;
    const radians = Math.atan2(mouse_x - center_x, mouse_y - center_y);
    const degree = (radians * (180 / Math.PI) * -1) + 180;
    crl.css('-moz-transform', 'rotate(' + degree + 'deg)');
    crl.css('-webkit-transform', 'rotate(' + degree + 'deg)');
    crl.css('-o-transform', 'rotate(' + degree + 'deg)');
    crl.css('-ms-transform', 'rotate(' + degree + 'deg)');
  }
}

function setMarkers() {  
  const markers = $('.menu-mark');
  const pie = 360 / markers.length;
  markers.each((index, elem) => {    
    $(elem).css('transform', `rotate(-${pie * index}deg)`);
  });
}

setMarkers();

mrk.mousedown(function (e) {
    mouseDown = true;    
});
$(document).mousemove(mouse);
$(document).mouseup(function (e) {
    mouseDown = false;
})