browse image not cropping properly - javascript

I have created an application using cropper.js for cropping an images. The application is working and the image is cropping, which can be seen in the preview.
After the first image is cropped, if you load a second image I am not able to crop. Also, when I double click on the image and then click again to drag, some unexpected movement of the image is happening.
Can anyone please tell me some solution for this
Plunker
script
var $image = $('.img-container > img'),
options = {
modal: true,
guides: true,
autoCrop: false,
dragCrop: true,
movable: true,
preview: '.preview',
crop: function(data) {
}
};

I'm a bit confused about the problem you're seeing, but this is what I see:
The second time I load an image into your Plunker the crop region disappears, but I can still click and drag a crop region.
The reason for this is the crop box element is display:none. This is because your old cropper has been hidden, and you need to reset() and clear() it before it can be used with the new image. You've already got the following:
$image.one('built.cropper', function () {
URL.revokeObjectURL(blobURL); // Revoke when load complete
}).cropper('reset', true).cropper('replace', blobURL);
but your missing clear()
$image.one('built.cropper', function () {
URL.revokeObjectURL(blobURL); // Revoke when load complete
}).cropper('reset', true).cropper('clear').cropper('replace', blobURL);
Plunker (since you asked so politely)

Related

destroy or reset image croppie

I have two different section for uploading image in the website, one of them for banner and another one for profile picture. They have different dimension as well. uploading image works in a overlay page.
I added image croppie in my server and according in my codes, when the user click on the banner image, it's automatically set its dimension to image croppie and when the user click on the profile picture, it set the profile picture size to image croppie.
All i want is, when user upload a photo and then cancel it, everything will be gone. Now if user upload a photo in banner photo, and then cancel it, the photo is still available when we come back to the overlay of uploading image. Also if user click on the profile picture, it shows the photo of the banner with its dimension again.
i want that when user clicks on cancel button (which is .fa-times in my codes), everything about the uploaded image and its dimension will be removed. Then if user click on the another section (profile photo or banner), the user see a fresh page with the right dimension.
Here is my codes, this is the codes, when user clicks on the browse button to select the image for uploading.
this.body.addClass("overlay--active");
var imageBody = $(e.target).closest(".icon");
this.height = imageBody.attr("data-height");
this.width = imageBody.attr("data-width");
var crop = new Croppie(document.getElementById('js-image-editor'), {
enableExif: true,
showZoomer: true,
viewport: { width: this.width, height: this.height, type: 'square'},
boundary: { width: this.width, height: this.height}
});
function readFile(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$('.section').addClass('ready');
// crop.croppie('bind', {
crop.bind({
url: e.target.result
}).then(function(){
console.log('jQuery bind complete');
});
}
reader.readAsDataURL(input.files[0]);
}
else {
swal("Sorry - you're browser doesn't support the FileReader API");
}
}
$('.button-upload-image').on('change', function () { readFile(this); });
$('.fa-save').on('click', function (ev) {
crop.result ({
type: 'canvas',
size: 'viewport'
}).then(function () {
console.log('upload image complete');
});
});
$(".fa-times").click(function() {
$('.section').removeClass('ready');
crop.bind ({
url: ''
}).then(function(){
console.log('reset complete');
});
})
as you can see in the last block, i tried to reset image croppie, but it's not working. Every time the error of "Croppie: Can't initialize croppie more than once" come up.
Anyone can help me on this? i really appreciate for your help in advance.
use $('.croppie').cropit('destroy'); than re intilize again.
The problem I've had with destroy is that once you destroy the instance, then you go to reinitialize croppie after that (say after a user cancels then decides to have another go), it gives a type error because the javascript object containing the html elements was deleted.
There's a workaround that others have found for this. But I found a better solution in my case was to utilize the one instance of croppie and toggle the visibility of the croppie container using css/jquery.
That being said. I think the main issue you are having is that upon cancel, you're trying to rebind to an empty URL rather than setting the value of the file upload to nothing. Use this instead.
$(".fa-times").click(function() {
$('.button-upload-image').val('');
});

Aviary Editor Loads blank image until screen is resized

So I have an instance of aviary editor on my site, it pulls images from filepicker and then resubmits them. The problem I am having is that when I load an image, it initially has a thumbnail I have loaded appear, then the screen goes blank...until I resize the screen and the image appears normally.
Here is what it looks like, notice the image dimensions in the bottom. They go from the already loaded thumbnail to a blank image, with the correct dimensions displayed until I slightly change the windows size.
While it is loading, dimensions of the thumbnail in bottom
After it has loaded, correct dimensions in bottom
After slightly changing window dimensions, the image appears
Here is my initialization code:
function initEditor( apiKey ){
var tools = ['enhance', 'orientation', 'focus', 'resize', 'crop', 'effects'];
var featherEditor = new Aviary.Feather({
apiKey: apiKey,
apiVersion: 3,
displayImageSize: true,
tools: tools,
maxSize: 800,
theme: 'minimum',
onSave: function(image, newUrl){
//onSave function, sends to external filePicker source
},
onError: function(errorObj){
console.log(errorObj);
},
onLoad: function(){
//load only if there is an img
if (typeof img !== 'undefined'){
openEditor(img, src, featherEditor);
}
}
});
return featherEditor;
}
Opening Code:
image = "img-id_image_relations-0-image"
src = "https://www.filepicker.io/api/file/mX42P6fLRS6YDP58moIH"
function openEditor(image, src, editor){
editor.launch({
image: image,
url: src
});
//return false;
}
Things I have tried:
Loading the image into a div before opening,
Simplifying the feather initialization to the bare minimum,
Test on external facing server and localhost,
What stinks is when I test it on jsFiddle it works perfectly. http://jsfiddle.net/TD4Ud/
It's very dirty, but I found a temporary solution of firing the window resize event when the image loads. I would love there to be a better answer, but this will work in the interim.
Add this as the onReady event in the initialization:
onReady: function(){
//this is an abomination but it works
window.dispatchEvent(new Event('resize'));
}

How to reset the Jcrop plugin? I.e. How to allow changing the source of the target image?

The application I'm working on allows users to add an unlimited number of images onto a viewport. With those images, a series of operations are allowed: resize, drag, rotate, and crop. For the cropping feature, I'm using the Jcrop plugin.
When clicking on the control icon for cropping, a lightbox appears, that shows the selected image (the <img> element is one and the same, only the src attribute value changes each time) and allows the user to crop it. The event handler associated triggered when the crop icon is clicked is:
$(document).on("click", "div.cropper", function(){
var ctrl = $(this),
ref = ctrl.attr("reference"),
obj = returnObj(objects,ref),
target = $("#crop-target")
crop_params = {};
target.attr("src",obj.src);
target.Jcrop({
onSelect: function(c){
crop_params = c;
}
});
});
Given the code above, the cropping works perfectly, but ONLY with the first image I try it on. When I click on the "cropper" icon for any other images after that, the first image is shown.
How can I work around this problem?
PS: I've searched through the already existing questions about Jcrop and couldn't find an answer to my particular problem.
You just need to create a new img tag and start jCrop with that.
$('#parent_tag #img_to_crop').remove();
$('#parent_tag').html('<img id="img_to_crop"></img>');
$('#parent_tag #img_to_crop').Jcrop({ options ... });

jCrop (jQuery) sometimes fails to load image/cropper area

I've got a pretty simple problem, but I've become clueless on what is causing the problem. In one of my applications I'm using jCrop as a small add-on to crop images to fit in banners/headers etc. These steps will be taken:
1) Select an image (using CKFinder for this, CKFinder returns the image path to an input field)
2) Click a button to load the image
3) Crop the image
4) Save the image
in about 75% of the cases everything goes according to plan, however the in the other 25% of the cases jCrop fails to load the cropping area and leaves it blank. Here's the jQuery code I'm using:
jQuery('#selectimg').live('click', function(e) {
e.preventDefault();
var newsrc = jQuery('#img2').val();
jQuery('#cropbox').attr('src', newsrc);
var jcrop_api = jQuery.Jcrop('#cropbox', {
boxWidth: 700,
boxHeight: 700,
onSelect: updateCoords,
onChange: updateCoords
});
//Some other JS code come's here for buttons (they work all the time)
});
I noticed that when I left the part away where #cropbox is being transformd in a cropable area, that the image is loading just fine, so the mistake lies with the var = jcrop_api part, but I slowsly start to think that there is no solution for this...
This is what I've tried so far:
Making a div <div id="cropper-box"></div> and use jQuery('#cropper-box').append('<img src="" id="cropbox" />'); and afterwards set the value. I tried the same thing but setting the image src in 1 step instead of afterwards.
I tried to put a placeholder on the page <img src="placeholder.png" id="cropbox" /> and change the source upon clicking the button. This works, but the cropperarea stays the size of the image (300x180px or something) and doesn't get bigger as it should.
// Edit:
Trying some more showed me that the image source is being replaced properly(! using Firefox to show the source for the selected text), I double checked the URL but this was a correct URL and a working image.
At the place where the cropper should be, there's an about 10x10 pixel white spot where the cropper icon (a plus sign) is popping up.. but as said before: the image isn't shown.
// Edit 2:
So I've took the sources for both the 1st and the 2nd try for the same image. As told before the first try the image won't load properly and the 2nd try it does (only when the 2nd try is the same image(!!)).
The selected page source shows 1 difference which is, first try:
<img style="position: absolute; width: 0px; height: 0px;" src="http://95.142.175.17/uploads/files/Desert.jpg">
second try:
<img style="position: absolute; width: 700px; height: 525px;" src="http://95.142.175.17/uploads/files/Desert.jpg">
I guess this is the image that's being replace by jCrop, but it's a complete riddle why it puts 0 heigth/width in there the first and the proper sizes the second time.
Okay guys, in case anyone else runs into this problem:
jCrop kinda gets messed up if the actions of loading an image and applying jCrop to it are queued too fast after eachother. I still find it strange that a second attempt works perfect, but I think that has something to do with cached image dimensions which are recognized by the DOM of the page or something.
The solution I came up with was by creating a function that converts the #cropbox into a jCrop area and then setting a 2 second interval, just to give jCrop some time to recognize the image and it's dimensions and then convert the element.
This is the part of html I used (with a preloader):
<div id="cropper-loading" style="display: none;"><img src="images/analytics/ajax-loader.gif" /></div>
<img id="cropbox" src="images/placeholder.png" style="display: none;" />
As you can see both the cropbox image and cropper-loading div are hidden as they are not needed instantly. You could display the placeholder if you wanted though.. Then this HTML form is used:
<input name="image2" id="img2" type="text" readonly="readonly" onclick="openKCFinder(this)" value="click here to select an image" style="width: 285px;" /> <button class="button button-blue" type="submit" name="load" id="selectimg">Load Image in cropper</button>
In my case I've been using KCFinder to load the images (it's part of CKEditor, really worth watching into!), KCFinder handles uploads, renaming etc and after choosing it returns the chosen image path (relative/absolute is configurable) to the input field.
Then when clicking #selectimg this code is called:
jQuery('#selectimg').click(function(e) {
e.preventDefault();
jQuery('#cropper-loading').css('display', 'block');
var newsrc = jQuery('#img2').val();
jQuery('#cropbox').attr('src', newsrc);
jQuery('#img').val(newsrc);
function createJcropArea() {
jQuery('#cropper-loading').css('display', 'none');
jQuery('#cropbox').css('display', 'block');
var jcrop_api = jQuery.Jcrop('#cropbox', {
boxWidth: 700,
boxHeight: 700,
onSelect: updateCoords,
onChange: updateCoords
});
clearInterval(interval);
}
var interval = setInterval(createJcropArea, 2000);
});
At first I prevent the link too be followed as it normally would (or button action) and after that the loading div is displayed (that's my reason for hiding the placeholder image, otherwise it would look messed up).
Then the image location is being loaded from the input field and copied into another (#img), this field is used to process the image afterwards (PHP uses the value of #img to load this image). Also simultaneously the #cropbox src is being set to the new image.
And here comes the part which solved my problem:
Instead of directly activating jCrop, I've made a function that:
1) hides the loading icon
2) displays the image
3) converts #cropbox into a jCrop area
4) clean the interval (otherwise it would loop un-ending)
And after this function you can see that, just to be save, I took 2 seconds delay before the jCrop area is being converted.
Hope it helps anyone in the future!
Cheers and thanks for thinking #vector and whoever else did ;-)
Creating an 'Image' object and setting up the 'src' attribute does not apply that you can treat the image like it had already been loaded.
Also, giving any fixed timeout interval does not guaranty the image has already been loaded.
Instead, you should set up an 'onload' callback for the Image Object - which will then initialize the Jcrop Object:
var src = 'https://example.com/imgs/someimgtocrop.jpg';
var tmpImg = new Image();
tmpImg.onload = function() {
//This is where you can safely create an image and a Jcrop Object
};
tmpImg.src = src; //Note that the 'src' attribute is only added to the Image Object after the 'onload' listener was defined
Try the edge library on the repo here: https://github.com/tapmodo/Jcrop
This should solve your problem. The lines that are changed to solve your problem:
// Fix size of crop image.
// Necessary when crop image is within a hidden element when page is loaded.
if ($origimg[0].width != 0 && $origimg[0].height != 0) {
// Obtain dimensions from contained img element.
$origimg.width($origimg[0].width);
$origimg.height($origimg[0].height);
} else {
// Obtain dimensions from temporary image in case the original is not loaded yet (e.g. IE 7.0).
var tempImage = new Image();
tempImage.src = $origimg[0].src;
$origimg.width(tempImage.width);
$origimg.height(tempImage.height);
}
Don't call this function onChange : updateCoords
Try it without and it will run smooth on mobiles.
You can create base64 directly and show them as an image wherever you want.
Here my weird but fantastic solution:
if (obj.tagName == 'IMG') {
var tempImage = new Image();
tempImage.src = $origimg[0].src;
$origimg.width(tempImage.width);
$origimg.height(tempImage.height);
if ($origimg[0].width > 1 && $origimg[0].height > 1) {
$origimg.width($origimg[0].width);
$origimg.height($origimg[0].height);
} else {
var tempImage = new Image();
tempImage.src = $origimg[0].src;
$origimg.width(tempImage.width);
$origimg.height(tempImage.height);
//console.log('error'+$origimg[0].width + $origimg[0].height);
}
I know this is old, but it was happening randomly to my install recently. Found that it was due to images not being full loaded before before jCrop intialized.
All it took to fix it was wrapping the jCrop initialization stuff inside of a
$(window).on("load", function () { //jcrop stuff here });
And it has been working well since.

Trouble with Galleria image gallery fade and default image

Using Galleria with frogCMS, but am currentl unable to create fading effects and to display a default image on load (currently only displaying an image on clicking a thumb)
$('ul.gallery').galleria(
onImage(image) { image.css('display','none').fadeIn(); } // not working.
);
// also not working
$('ul.gallery').galleria({
history : true, // activates the history object for bookmarking, back-button etc.
clickNext : true, // helper for making the image clickable
insert : '#main_image', // the containing selector for our main image
onImage : function(image,caption,thumb) { // let's add some image effects for demonstration purposes
// fade in the image & caption
if(! ($.browser.mozilla && navigator.appVersion.indexOf("Win")!=-1) ) { // FF/Win fades large images terribly slow
image.css('display','none').fadeIn(1000);}
});
});
Any implimentation help would be great!
I knocked up a Galleria plugin for a CMS called Indexhibit a few years ago.
Here's the original thread if you're interested.
I believe this should help with default image on load: -
$('galleria li:first').addClass('active');
Do you have live/static demo to view? Which version did you base your gallery on?
The simple or the advanced version?
Also checkout the live demo I for the above mentioned plugin.
Fadiing/transitions work fine. Feel free to copy+paste what you need.
Hope this helps.

Categories