tags:

views:

691

answers:

4

Hi guys!

Im working on a new feature in my site and I got stucked really bad. Im using JCrop obviously to crop an Image on my website.

The new feature that I've been asked to Implement is to allow the user to change the colors of the Image being cropped.

I have now 3 images , Color, GrayScale and Sepia.

I can change the source of the image tag using javascript so the image gets changed without reload but I cannot do this once the JCrop has been enabled because it replaces the original Image for a new one.

I thought I could disable JCrop, Replace the Image and then Re-Enable, but i couldnt do such thing.

The example I found where the JCrop gets destroyed (example5 in Demo zip) uses an object :

jcrop_api = $.Jcrop('#cropbox');

But Im enabling JCrop in a different manner,more like Example 3 :

            jQuery('#cropbox').Jcrop({
                onChange: showPreview,
                onSelect: showPreview,
                aspectRatio: 1
            });

How can I destroy JCrop so I can replace te Image? Is there another way to do this?

Please help!

I Could easily reload the page each time the user changes de color of the image but we all know that's not cool.

Any comments will be apreciated.

Thanks

+2  A: 

First question is if the images you are swapping are the same size? If they are, the following should work:

$(document).ready(function(){
    // Just pulled some creative commons images off flickr for testing.
    var one = "http://farm5.static.flickr.com/4034/4580633003_e62e061b64_d.jpg";
    var two = "http://farm5.static.flickr.com/4060/4580650483_7881505c66_d.jpg";
    var three = "http://farm5.static.flickr.com/4034/4581278976_0c91bc0f6f_d.jpg";

    var api;

    function showPreview(){ alert('Changed'); }

    function setCrop()
    {
        api = $.Jcrop('#cropBox',{ aspectRatio: 1, onSelect: showPreview });
    }

    // Setup Jcrop for the original image
    setCrop();

    // Change the image and reset Jcrop
    $('#button').click(function(){
        api.destroy();
        var i = $('#cropBox').get(0).src = three;
        setCrop();
    });    

});

If your images are different sizes (swapping a portrait for landscape?) things are a little more complicated. You will need to wait for the image to load so Jcrop can get the correct size of the new image. The vanilla javascript setTimeout function will work, but since it runs in global scope, you need to define a few things gloabally. The downside is that you have to wait a second or two before you can crop.

$(document).ready(function(){

    var one = "http://farm5.static.flickr.com/4034/4580633003_e62e061b64_d.jpg";
    var two = "http://farm5.static.flickr.com/4060/4580650483_7881505c66_d.jpg";
    var three = "http://farm5.static.flickr.com/4034/4581278976_0c91bc0f6f_d.jpg";

    // api needs to be defined globally so it can be accessed from the setTimeout function
    $.globalEval("var api;");

    // Also need to define your showPreview globally.
    $.globalEval("function showPreview(){ alert('Changed'); }");

    function setCrop()
    {
        // Need to pause a second or two to allow the image to load, otherwise the Jcrop plugin
        // will not update the image size correctly and if you change image size the picture
        // will be stretched.
        // Change the 1000 to however many seconds you need to load the new image.
        setTimeout("api = $.Jcrop('#cropBox',{ aspectRatio: 1, onSelect: showPreview     });",1000);
    }

    // Setup Jcrop for the original image
    setCrop();

    // Change the image and reset Jcrop
    $('#button').click(function(){
        api.destroy();
        var i = $('#cropBox').get(0).src = two;
        setCrop();
    });    

});

That should help you out. Everything tested out for me on FireFox over at jsFiddle. You can try it out here.

AdmSteck
A: 

I have the same problem and the answer works well. However, is ther a way to be more efficient I mean initialize the jcrop as soon as the image is loaded ??

Somethine like if (img.complete) ....

Thanks in advance for help

sparky
Simply change `api = $.Jcrop('#cropBox',{ aspectRatio: 1, onSelect: showPreview });` to include the initial location and size of the box: `api = $.Jcrop('#cropBox',{ aspectRatio: 1, onSelect: showPreview, setSelect: [ 100, 100, 50, 50 ]});`
AdmSteck
A: 

Good question! Followings may save our time,

function initJcrop(id) {

jcrop_api = $.Jcrop('#'+id, {

onSelect:   showCoords,
onChange:   showCoords,
bgColor:    'black',
bgOpacity:  .4,
boxWidth:   picture_width,
boxHeight:  picture_height,
setSelect:   [ (picture_width * 4/5), 
               (picture_height * 4/5), 
               (picture_width/5),
               (picture_height/5) ]

}); }

function stopJcrop() { jcrop_api.destroy(); return (false); }

/* Example in use */

$('#start_button').bind('click', function() { $('#image_file').attr('src', server_file); initJcrop('raw_file'); });

$('#end_button').bind('click', function() { stopJcrop(); });

Sun
A: 

Hi Bathan,

I've come across this situation. I've put my jcropimage(#cropbox) on a div and just empty the html of the div. See code below

javascript:



try {
   $("#workspace").html('');
   } catch (Error)
   { }

//add cropbox on the fly
$("#workspace").prepend(//create img tag with id "cropbox" here... i can't seem to post my code - Stack Overflow mechanism);
$('#cropbox').attr("src", 'path/to/image');
$('#cropbox').Jcrop();

Hope this helps.

jrom