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...