title: css 3d transform rotate (x + y) using mouse drag
body: <p>i was recently diving into the world of css transform and wanted to rotate a div (x and y axis), i was able to do it with 2 sliders with 0 to 360 degree range but now looking forward to do it with dragging the mouse, i have made a very sloppy effort on that looking for suggestion to fix it:</p>
  <p><a href="https://jsfiddle.net/uk32yasf/2/" rel="nofollow noreferrer">jsfiddle link to test</a></p>
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>"use strict";
  
  let elContainer = $('#container');
  let elBox = $('#box');
  
  $(document).ready(function() {
    $('.slider-rotate').on('input', function() {
      sliderRotate();
    });
  
    elContainer.mousedown(function(e) {
      initDragRotate(e);
    });
  
    elContainer.mousemove(function(e) {
      dragRotate(e);
    });
  
    elContainer.mouseup(function(e) {
      endDragRotate();
    });
  
  });
  
  let dragging = false;
  let delta = {};
  
  function initDragRotate(e) {
    dragging = true;
    delta = {
      x: e.pageX,
      y: e.pageY,
    };
  }
  
  function dragRotate(e) {
    if (!dragging) {
      return;
    }
  
    delta.x = e.pageX - delta.x;
    delta.y = e.pageY - delta.y;
  
    let rotateParam = '';
    rotateParam += ' rotate' + 'Y' + '(' + delta.x + 'deg)';
    rotateParam += ' rotate' + 'X' + '(' + delta.y + 'deg)';
    elBox.css('transform', rotateParam);
  }
  
  function endDragRotate() {
    if (!dragging) {
      return;
    }
  
    dragging = false;
  }
  
  
  function sliderRotate() {
    let rotateParam = '';
    $('.slider-rotate').each(function() {
      rotateParam += ' ' + getRotateParamString($(this));
    });
    elBox.css('transform', rotateParam);
  }
  
  function getRotateParamString(elClass) {
    let val = elClass.val();
    let rotateType = elClass.data('rotateType');
    let rotateParam = 'rotate' + rotateType + '(' + val + 'deg)';
  
    return rotateParam;
  }</code></pre>
  <pre class="snippet-code-css lang-css prettyprint-override"><code>#container {
    background: #ccc;
    padding: 10vh;
    display: flex;
    align-items: center;
    justify-content: center;
  }
  
  #box {
    width: 30vh;
    height: 30vh;
    border: 5px solid #000;
    position: relative;
    transform-style: preserve-3d;
  }
  
  #box&gt;div {
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
  }</code></pre>
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"&gt;&lt;/script&gt;
  &lt;div id="container"&gt;
    &lt;div id="box"&gt;
      &lt;div style="background: #f00;"&gt;&lt;/div&gt;
      &lt;div style="background: #0f0;"&gt;&lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
  
  &lt;div id="control"&gt;
    &lt;br&gt;
    &lt;label&gt;
      x
      &lt;input type="range" class="slider-rotate" data-rotate-type="X" min="0" max="360" value="0"&gt;
    &lt;/label&gt;
    &lt;br&gt;
    &lt;label&gt;
      y
      &lt;input type="range" class="slider-rotate" data-rotate-type="Y" min="0" max="360" value="0"&gt;
    &lt;/label&gt;
  &lt;/div&gt;</code></pre>
  </div>
  </div>
  </p>
  <p>also, there's 2 div on top and bottom (green and red) with transform-style preserve-3d property, hoping that it's show the other color when flipped but no luck! please suggest, thanks!</p>