I work a form that would let users to select an image on their computer, crop it and finally upload as profile image. I use JCrop to crop the photo. After a lot of struggles, now everything seems to work fine, except that if the user changes its mind and would like to browse in a second image, the image is not replaced on my form. I do replace the src attribute of the 'preview' image, but it seems that somehow JCrop still stores the previous image and this somehow "covers" the new image. I tried to use the JCrop setImage method to replace the image, but it does not seem to work. Any hints on how to fix this? Please see the code samples below.
var currentFile;
var file;
var options;
// convert bytes into friendly format
function bytesToSize(bytes) {
var sizes = ['Bytes', 'KB', 'MB'];
if (bytes == 0) return 'n/a';
var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));
return (bytes / Math.pow(1024, i)).toFixed(1) + ' ' + sizes[i];
};
// check for selected crop region
function checkForm() {
if (parseInt($('#w').val())) return true;
jQuery('.error').html('Please select a crop region and then press Upload').show();
return false;
};
// update info by cropping (onChange and onSelect events handler)
function updateInfo(e) {
jQuery('#x1').val(e.x);
jQuery('#y1').val(e.y);
jQuery('#x2').val(e.x2);
jQuery('#y2').val(e.y2);
jQuery('#w').val(e.w);
jQuery('#h').val(e.h);
};
// clear info by cropping (onRelease event handler)
function clearInfo() {
jQuery('.info #w').val('');
jQuery('.info #h').val('');
};
function fileSelectHandler(evt) {
// hide all errors
jQuery('.error').hide();
// grabbing image
evt.preventDefault()
var target = evt.target
file = target && target.files && target.files[0]
if (!file) {
jQuery('.error').html('Image not found.').show();
jQuery('#main_photo').val('');
return;
}
var oFile = target.files[0];
// check for image type (jpg is allowed)
var rFilter = /^(image\/jpeg)$/i;
if (! rFilter.test(oFile.type)) {
jQuery('.error').html('Please select a valid image file (jpg)').show();
jQuery('#main_photo').val('');
return;
}
// check for file size
if (oFile.size > 5 * 1024 * 1024) {
jQuery('.error').html('You have selected too big file (max: 5 MB), please select a one smaller image file').show();
jQuery('#main_photo').val('');
return;
}
//setting options for image loader
options = {
orientation: true,
maxWidth: 400
}
// preview element
var oImage = document.getElementById('preview');
// adding onload event handler to initialize JCrop
oImage.onload = function () {
// Create variables (in this scope) to hold the Jcrop API and image size
var jcrop_api, boundx, boundy;
console.log(oImage);
// destroy Jcrop if it is existed
if (typeof jcrop_api != 'undefined') {
jcrop_api.destroy();
jcrop_api = null;
}
// initialize Jcrop
jQuery('#preview').Jcrop({
minSize: [32, 32], // min crop size
aspectRatio : 200/250, // keep aspect ratio 1:1
bgFade: true, // use fade effect
bgOpacity: .3, // fade opacity
trueSize: [oImage.naturalWidth,oImage.naturalHeight],
onChange: updateInfo,
onSelect: updateInfo,
onRelease: clearInfo
}, function(){
// use the Jcrop API to get the real image size
var bounds = this.getBounds();
boundx = bounds[0];
boundy = bounds[1];
// Store the Jcrop API in the jcrop_api variable
jcrop_api = this;
console.log(jQuery('#preview').attr('src'));
jcrop_api.setImage(jQuery('#preview').attr('src'));
});
};
displayImage(file, options);
}
/**
* Updates the results view
*
* @param {*} img Image or canvas element
* @param {object} [data] Meta data object
*/
function updateResults(img, data) {
var fileName = currentFile.name
var href = img.src
var dataURLStart
var content
if (!(img.src || img instanceof HTMLCanvasElement)) {
content = jQuery('<span>Loading image file failed</span>')
} else {
if (!href) {
href = img.toDataURL(currentFile.type + 'REMOVEME')
// Check if file type is supported for the dataURL export:
dataURLStart = 'data:' + currentFile.type
if (href.slice(0, dataURLStart.length) !== dataURLStart) {
fileName = fileName.replace(/\.\w+$/, '.png')
}
}
content = jQuery('<a target="_blank">')
.append(img)
.attr('download', fileName)
.attr('href', href)
}
jQuery('#preview').attr("src", href);
}
/**
* Displays the image
*
* @param {File|Blob|string} file File or Blob object or image URL
* @param {object} [options] Options object
*/
function displayImage(file, options) {
currentFile = file
if (!loadImage(file, updateResults, options)) {
jQuery('.error').html('Incompatible browser. Image cannot be displayed.').show();
jQuery('#main_photo').val('');
return;
}
}