JSFiddle - React, Tailwind, and code Playground

HTML

<link rel="stylesheet" href="http://ajax.aspnetcdn.com/ajax/bootstrap/2.3.1/css/bootstrap.min.css">
<link rel="stylesheet" href="http://ajax.aspnetcdn.com/ajax/bootstrap/2.3.1/css/bootstrap-responsive.min.css">
<div id="container" style="margin-left: 120px;">
    <canvas id="buffer" class="canvasoverlays"></canvas>
    <canvas id="overlay" class="canvasoverlays"></canvas>
</div>
<script src="http://cdnjs.cloudflare.com/ajax/libs/rxjs/2.5.3/rx.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/rxjs/2.5.3/rx.binding.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/rxjs-dom/2.5.3/rx.dom.js"></script>

CSS

#container {
    position: relative;
}

.canvasoverlays {
    position: absolute;
}

.handle {
    position: absolute;
    width: 20px;
    height: 20px;
    background-color: rgba(255,255,255,0.5);
    border: 1px solid rgba(0,0,0,0.5);
    user-select: none;
}

.handle#tr {
    margin-left: -20px;
}

.handle#t, .handle#b {
    margin-left: -10px;
}

.handle#r, .handle#l {
    margin-top: -10px;
}

.handle#br {
    margin-left: -20px;
    margin-top: -20px;
}

.handle#bl {
    margin-top: -20px;
}

JavaScript

(function (global) {

    var // a model for the region of the image about to be cropped
        boundingBox,
        // an array of draggable elements that modify the crop region
        handles = [],
        // `overlay` is a canvas element that allows us to darken the portion  of the image that will be removed.
        overlay,
        // `ctx` will be the drawing context for `overlay`
        ctx;

    function loadImage () {
        var // `buffer` is a canvas element that displays the actual image to crop
            buffer = document.querySelector('#buffer'),
            // `img` is an img element we use to load the img, though we never add it to the DOM
            img = document.createElement('img');

        img.src = 'https://raw.github.com/Reactive-Extensions/RxJS/master/examples/crop/images/leaf%20twirl.jpg';

        // Returns an observable which fires when the image is loaded
        return Rx.DOM.fromEvent(img, 'load').select(function () {
            overlay.width = img.width;
            overlay.height = img.height;

            buffer.width = img.width;
            buffer.height = img.height;
            buffer.getContext('2d').drawImage(img, 0, 0);

            return {
                width: img.width,
                height: img.height
            };
        });
    } 

    function initBoundingBox(size) {
        boundingBox = {
            x: 0,
            y: 0,
            x2: size.width,
            y2: size.height
        };
    }

    function createHandles () {
        var container = document.getElementById('container');

        function createHandle (id, render, updateModel) {
            var handle = document.createElement('div');
            handle.className += ' handle';
            handle.setAttribute('id', id);
            container.appendChild(handle);

            // `render` allows us to visually update the handle after it has been dragged
            handle['render'] = render;
            // `updateModel` allows us to...