Circle Cropper

A good example of how transform origin does its bizniz

HTML

<div id="cropper">
    <img id="cropper-img" src="https://i.imgur.com/rpEuuFI.jpg">
    <div class="drag-and-drop-preventer"></div>
    <div class="white-circle"></div>
    <div class="black-circle"></div>
  </div>
  <input type="range" min="10" max="400" value="100"/>

<hr style="clear:both">

  <form id="cropping_result">
    <input id="top" type="number" disabled>
    <label for="top">top</label>
    <br>
    <input id="left" type="number" disabled>
    <label for="left">left</label>
    <br>
    <input id="bottom" type="number" disabled>
    <label for="bottom">bottom</label>
    <br>
    <input id="right" type="number" disabled>
    <label for="right">right</label>
  </form>

CSS

::-moz-selection { background-color: transparent; }
::selection { background-color: transparent; }

#cropper{
  width:500px;
  height:500px;
  border:solid 4px black;
  position:relative;
  cursor: -webkit-grab;
  overflow:hidden;
}

#cropper-img{
  position:absolute;
  top:50%;
  left:50%;
  -webkit-transform-origin:0 0;
          transform-origin:0 0;
  -webkit-transition:-webkit-transform 2.0;
          transition:-webkit-transform 2.0;
}

.drag-and-drop-preventer{
  position:absolute;
  width:100%;
  height:100%;
  background-color:transparent;
}

.white-circle,
.black-circle{
  position:absolute;
  border-radius:50%;
}

.white-circle{
  top:50px;
  left:50px;
  width:398px;
  height:398px;
  border:solid 1px white;
}
.black-circle{
  top:49px;
  left:49px;
  width:400px;
  height:400px;
  border:solid 1px black;
}

input[type=range]{
  width:500px;
}

JavaScript

/**
*   Circle Cropper 4000
*   built for Mozillians.org
*   Wray Bowling [:wbowling] Jun 2014
*/

// DOM
var cropper = document.querySelector('#cropper');
var cropperImage = document.querySelector('#cropper img');
var slider = document.querySelector('input');

var originalWidth, originalHeight;
var originalScale, slideScale, reverseScale;
var x,y,px,py;
var top,bottom,left,right;

slideScale = 1.0;

function update(){
    //translate based on inverse scale
    //transform stays fixed (see CSS)
    //scale based on scale

    var transformString = [];
    scale = originalScale * slideScale;
    transformString.push('scale('+ scale +')');
    transformString.push('translate('+x+'px,'+y+'px)');

    //console.log(transformString);

    cropperImage.style.webkitTransformOrigin = '0 0';
    cropperImage.style.transformOrigin = '0 0';
    cropperImage.style.webkitTransform = transformString.join(' ');
    cropperImage.style.transform = transformString.join(' ');

    console.log(
      'scale:'+scale.toFixed(4),
      'reverse:'+reverseScale.toFixed(4),
      'x',x,
      'y',y
    );

    document.getElementById('top').value = Math.round(-200 * reverseScale - y);
    document.getElementById('left').value = Math.round(-200 * reverseScale - x);
    document.getElementById('bottom').value = Math.round(200 * reverseScale - y);
    document.getElementById('right').value = Math.round(200 * reverseScale - x);
}

cropperImage.onload = function(){
    originalWidth = cropperImage.width;
    originalHeight = cropperImage.height;
    //console.log('original WxH',originalWidth,originalHeight);

    if(originalWidth >= originalHeight){
        originalScale = 500 / originalWidth;
    }else{
        originalScale = 500 / originalHeight;
    }

    x = -originalWidth / 2;
    y = -originalHeight / 2;
    //console.log('originalScale',originalScale);
    update();
};

var dragging = false;

// EVENTS
cropper.onmousedown = function(event){
    dragging = true;
};

window.onmouseup =...