JSFiddle - React, Tailwind, and code Playground
HTML
<form id="form">
<h1>Client side image file selector and cropper</h1>
<h2>Image file select</h2>
<input id="file" type="file" />
<h2>Image cropper (Jcrop)</h2>
<div id="jcrop"></div>
<h2>Real size cropped image preview (canvas)</h2>
<canvas id="canvas"></canvas>
<input id="png" type="hidden" />
<h2>Submit form</h2>
<input type="submit" value="Upload form data and image" />
</form>
CSS
/* jquery.Jcrop.min.css v0.9.12 (build:20130126) */
.jcrop-holder{direction:ltr;text-align:left;}
.jcrop-vline,.jcrop-hline{background:#FFF url(Jcrop.gif);font-size:0;position:absolute;}
.jcrop-vline{height:100%;width:1px!important;}
.jcrop-vline.right{right:0;}
.jcrop-hline{height:1px!important;width:100%;}
.jcrop-hline.bottom{bottom:0;}
.jcrop-tracker{-webkit-tap-highlight-color:transparent;-webkit-touch-callout:none;-webkit-user-select:none;height:100%;width:100%;}
.jcrop-handle{background-color:#333;border:1px #EEE solid;font-size:1px;height:7px;width:7px;}
.jcrop-handle.ord-n{left:50%;margin-left:-4px;margin-top:-4px;top:0;}
.jcrop-handle.ord-s{bottom:0;left:50%;margin-bottom:-4px;margin-left:-4px;}
.jcrop-handle.ord-e{margin-right:-4px;margin-top:-4px;right:0;top:50%;}
.jcrop-handle.ord-w{left:0;margin-left:-4px;margin-top:-4px;top:50%;}
.jcrop-handle.ord-nw{left:0;margin-left:-4px;margin-top:-4px;top:0;}
.jcrop-handle.ord-ne{margin-right:-4px;margin-top:-4px;right:0;top:0;}
.jcrop-handle.ord-se{bottom:0;margin-bottom:-4px;margin-right:-4px;right:0;}
.jcrop-handle.ord-sw{bottom:0;left:0;margin-bottom:-4px;margin-left:-4px;}
.jcrop-dragbar.ord-n,.jcrop-dragbar.ord-s{height:7px;width:100%;}
.jcrop-dragbar.ord-e,.jcrop-dragbar.ord-w{height:100%;width:7px;}
.jcrop-dragbar.ord-n{margin-top:-4px;}
.jcrop-dragbar.ord-s{bottom:0;margin-bottom:-4px;}
.jcrop-dragbar.ord-e{margin-right:-4px;right:0;}
.jcrop-dragbar.ord-w{margin-left:-4px;}
.jcrop-light .jcrop-vline,.jcrop-light .jcrop-hline{background:#FFF;filter:alpha(opacity=70)!important;opacity:.70!important;}
.jcrop-light .jcrop-handle{-moz-border-radius:3px;-webkit-border-radius:3px;background-color:#000;border-color:#FFF;border-radius:3px;}
.jcrop-dark .jcrop-vline,.jcrop-dark .jcrop-hline{background:#000;filter:alpha(opacity=70)!important;opacity:.7!important;}
.jcrop-dark .jcrop-handle{-moz-border-radius:3px;-webkit-border-radius:3px;background-color:#FFF;border-color:#000;border-radius:3px;}
.solid-line...
JavaScript
$("#file").change(function(){
picture(this);
});
$("#form").submit(function(e){
e.preventDefault();
//Get cropped image base64 string
var base64 = $("#png").val();
//Remove base64 string value from #png input to prevent it form being sent
$("#png").val("");
//Get formdata
formData = new FormData($(this)[0]);
//Convert base64 string to file blob
var blob = dataURLtoBlob(base64);
//Add file blob to the form data
formData.append("cropped_image[]", blob);
$.ajax({
url: "whatever.php",
type: "POST",
data: formData,
contentType: false,
cache: false,
processData: false,
success: function(data){
alert("Succes");
},
error: function(data){
alert("Error");
},
complete: function(data) {
//Add base64 string value back to #png input
$("#png").val(base64);
}
});
});
var picture_width;
var picture_height;
var crop_max_width = 300;
var crop_max_height = 300;
function picture(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$("#jcrop, #preview").html("").append("<img src=\""+e.target.result+"\" alt=\"\" />");
picture_width = $("#preview img").width();
picture_height = $("#preview img").height();
$("#jcrop img").Jcrop({
onChange: canvas,
onSelect: canvas,
boxWidth: crop_max_width,
boxHeight: crop_max_height
});
}
reader.readAsDataURL(input.files[0]);
}
}
function canvas(coords){
var imageObj = $("#jcrop img")[0];
var canvas = $("#canvas")[0];
canvas.width = coords.w;
canvas.height = coords.h;
var context = canvas.getContext("2d");
context.drawImage(imageObj, coords.x, coords.y, coords.w, coords.h, 0, 0, canvas.width, canvas.height);
png();
}
function png() {
var png = $("#canvas")[0].toDataURL('image/png');
$("#png").val(png);
}
function dataURLtoBlob(dataURL) {
var BASE64_MARKER = ';base64,';
if(dataURL.indexOf(BASE64_MARKER) == -1) {
var parts = dataURL.split(',');
var contentType =...