I am working on a component in which there is file-upload HTML control, upon selecting an image using the file-upload element, the image would be rendered on the HTML5 Canvas element.
Here is JSFiddle with sample code: https://jsfiddle.net/govi20/spmc7ymp/
id=target => selector for jcrop element
id=photograph => selector for fileupload element
id=preview => selector for canvas element
id=clear_selection => selector for a button which would clear the canvas
Third-party JS libraries used:
<script src="./js/jquery.min.js"></script>
<script src="./js/jquery.Jcrop.js"></script>
<script src="./js/jquery.color.js"></script>
Setting up the JCrop:
<script type="text/javascript">
jQuery(function($){
var api;
$('#target').Jcrop({
// start off with jcrop-light class
bgOpacity: 0.5,
keySupport: false,
bgColor: 'black',
minSize:[240,320],
maxSize:[480,640],
onChange : updatePreview,
onSelect : updatePreview,
height:160,
width:120,
addClass: 'jcrop-normal'
},function(){
api = this;
api.setSelect([0,0,240,320]);
api.setOptions({ bgFade: true });
api.ui.selection.addClass('jcrop-selection');
});
});
clear canvas event which will be triggered on clear button click event:
jQuery('#clear_selection').click(function(){
$('#target').Jcrop({
setSelect: [0,0,0,0],
});
});
code that renders image on HTML5 Canvas:
function readURL(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$('#target').attr('src', e.target.result);
setProperties();
}
reader.readAsDataURL(input.files[0]);
}
}
function setProperties(){
$('#target').Jcrop({
setSelect: [0,0,240,320]
});
}
$("#photograph").change(function(){
readURL(this);
});
code to crop and render an image on the canvas:
var canvas = document.getElementById('preview'),
context = canvas.getContext('2d');
make_base();
function updatePreview(c) {
console.log("called");
if(parseInt(c.w) > 0) {
// Show image preview
var imageObj = $("#target")[0];
var canvas = $("#preview")[0];
var context = canvas.getContext("2d");
context.drawImage(imageObj, c.x, c.y, c.w, c.h, 0, 0, canvas.width, canvas.height);
}
};
function make_base() {
console.log("make_base called");
var base_image = new Image();
base_image.src = '';
base_image.onload = function () {
context.drawImage(base_image, 0, 0);
}
}
Here are a bunch of issues I am facing with the above setup:
- updatePreview function is not getting called on selection, hence the canvas is not getting rendered.
- crop selection box is not draggable (I am using bootstrap CSS, I suspect it is due to missing/mismatching dependency).
- Canvas is
HTML5
element, which means the end-user must have anHTML5
compatible browser, I am working on an app that has millions of users. Forcing users to use the latest browser is not a feasible option. What should be the fallback mechanism here?