JSFiddle - React, Tailwind, and code Playground
by hiral
HTML
<div id="container" class="inline relative">
<div id="preview">
<img class="preview-image relative block" height="360" width="640" src="http://i.imgur.com/tBkSTZC.jpg" />
</div>
<div id="cropper" class="absolute">
<div class="relative full-height full-width">
<div class="inline resize-container top-left absolute" data-resize="tl">
<div class="resize inline"></div>
</div>
<div class="inline resize-container top-right absolute" data-resize="tr"> <span class="resize inline"></span>
</div>
<div class="inline resize-container bottom-left absolute" data-resize="bl"> <span class="resize inline"></span>
</div>
<div class="inline resize-container bottom-right absolute" data-resize="br"> <span class="resize inline"></span>
</div>
</div>
</div>
</div>
<h2>Preview</h2>
<canvas class="canvas block"></canvas>
CSS
* {
margin:0;
padding:0;
}
.absolute {
position:absolute;
}
.relative {
position:relative;
}
.block {
display:block;
}
.inline {
display:inline-block;
}
.inline.hide, .hide {
display:none;
}
.full-height {
height:100%;
}
.full-width {
width:100%;
}
#container {
overflow:hidden;
}
#cropper {
height:100px;
width:200px;
opacity:0.9;
top:0px;
left:0px;
box-shadow:0 0 0 1px #CCC, 0 0 0 1000px rgba(0, 0, 0, 0.7);
cursor:move;
}
#drop {
height:100px;
}
.resize {
height:10px;
width:10px;
border:1px solid #333;
background-color:white;
margin-bottom:2px;
}
.resize-container {
padding:15px;
height:12px;
width:12px;
margin-top:-22px;
z-index:1;
}
.resize-container.bottom-left {
cursor:sw-resize;
}
.resize-container.bottom-right {
cursor:se-resize;
}
.resize-container.top-left {
cursor:nw-resize;
}
.resize-container.top-right {
cursor:ne-resize;
}
.resize-container.bottom-right, .resize-container.top-right {
right:0;
}
.resize-container.bottom-left, .resize-container.bottom-right {
bottom:-22px;
}
.resize-container.bottom-left, .resize-container.top-left {
margin-left:-22px;
}
.resize-container.bottom-right, .resize-container.top-right {
margin-right:-22px;
}
JavaScript
var cropper = "#cropper",
cropw = 200,
croph = 100,
resize = ".resize-container";
image_events(cropw, croph);
$(".preview-image").load(function () {
show_cropped_img();
});
function show_cropped_img(swidth, sheight) {
var canvas = $("canvas")[0],
x, y,
position = $(cropper).position();
x = position.left;
y = position.top;
canvas.width = cropw;
canvas.height = croph;
if (!swidth) {
swidth = cropw;
}
if (!sheight) {
sheight = croph;
}
var ctx = canvas.getContext("2d");
ctx.drawImage($("#preview").find(".preview-image")[0], x, y, swidth, sheight, 0, 0, cropw, croph);
$(".canvas").removeClass("hide");
}
function image_events(width, height) {
crop_events();
resize_events();
function crop_events() {
$(cropper).on("mousedown", function () {
$(this).on("mousemove", start_move);
});
$(cropper).on("mouseup", leave);
$(cropper).on("mouseleave", leave);
function start_move(event) {
var x = event.pageX - width / 2,
maxw = $("#preview").width() - width,
maxh = $("#preview").height() - height,
swidth = $(cropper).width(),
sheight = $(cropper).height();
if (x > maxw) {
x = maxw;
}
if (y > maxh) {
y = maxh;
}
if (x < 0) {
x = 0;
}
if (y < 0) {
y = 0;
}
$(cropper).offset({
left: x,
top: y
});
show_cropped_img(swidth, sheight);
}
function leave() {
$(cropper).off("mousemove", start_move);
}
}
function resize_events() {
$(resize).mousedown(function () {
$(this).on("mousemove", start_resize);
});
$(resize).on("mouseup", leave);
...