Using jcrop on responsive images
Asked Answered
L

5

16

Since jcrop is now working on touch screens I want to do a web app that uses it. I have everything working on it but if I try to make the design responsive so that the user can see the whole image before cropping (it's width is a percentage of the screen) then the cropped area won't be the same as the selected by the user. The coordinates of the selection made on top of the resized image won't match the ones on the full size image.

Jcrop includes a solution to a similar issue (when handling huge images) by using box sizing or the truesize method but none of them work if the width of the image is based on percentages, instead of a given width in pixels.

The only solution I can think of is to resize the image using media queries and make 3 or 4 versions depending on the width of the screen but I'd rather stick to the percentage based resize because it looks much better.

This is my jcrop call:

      var jcrop_api, boundx, boundy;
    $('#target').Jcrop({
        onChange: updatePreview,
        onSelect: updatePreview,
        aspectRatio: 0.75
    },function(){
        // Use the API to get the real image size
        var bounds = this.getBounds();
        boundx = bounds[0];
        boundy = bounds[1];
        trueSize: [900,600],
        // Store the API in the jcrop_api variable
        jcrop_api = this;
    });
            function updatePreview(c){
        if (parseInt(c.w) > 0){
            var rx = <?echo $width;?> / c.w;
            var ry = <?echo $height;?> / c.h;

            $('#preview').css({
                width: Math.round(rx * boundx) + 'px',
                height: Math.round(ry * boundy) + 'px',
                marginLeft: '-' + Math.round(rx * c.x) + 'px',
                marginTop: '-' + Math.round(ry * c.y) + 'px'
            });
        }

        $('#x').val(c.x);
        $('#y').val(c.y);
        $('#w').val(c.w);
        $('#h').val(c.h);

    };
Leroi answered 30/11, 2012 at 15:28 Comment(1)
I'm having trouble figuring out how to even get the image to be responsive. Once I call Jcrop, it stops being responsive for me.Fluxion
L
15

TrueSize ended up doing the trick, I wasn't using it properly:

jQuery(function($){

    // Create variables (in this scope) to hold the API and image size
    var jcrop_api, boundx, boundy;

    $('#target').Jcrop({
        onChange: updatePreview,
        onSelect: updatePreview,
        aspectRatio: 0.75,
        trueSize: [<?echo $width2;?>,<?echo $height2;?>]
    },function(){
        // Use the API to get the real image size
        var bounds = this.getBounds();
        boundx = bounds[0];
        boundy = bounds[0.75];
        //trueSize: [ancho,alto],
        // Store the API in the jcrop_api variable
        jcrop_api = this;
    });

    function updatePreview(c){
        if (parseInt(c.w) > 0){
            var rx = <?echo $width;?> / c.w;
            var ry = <?echo $height;?> / c.h;

            $('#preview').css({
                width: Math.round(rx * boundx) + 'px',
                height: Math.round(ry * boundy) + 'px',
                marginLeft: '-' + Math.round(rx * c.x) + 'px',
                marginTop: '-' + Math.round(ry * c.y) + 'px'
            });
        }

        $('#x').val(c.x);
        $('#y').val(c.y);
        $('#w').val(c.w);
        $('#h').val(c.h);

    };


});
Leroi answered 4/12, 2012 at 8:32 Comment(6)
where does $width2 and $height2 come from?Tralee
I managed to get it to work by setting truesize to the following values. trueSize: [oImage.naturalWidth,oImage.naturalHeight],Armentrout
where does $width2 and $height2 come from?Dotti
@Dotti <?echo $width2;?> is PHP code. Elaine probably measures the width and height of the image with PHP and prints it in the JavaScript code.Kee
I get the error: "ReferenceError: boundx is not defined".Kee
Why a $width & $height and $width2 & $height2 ?Buddy
A
1

It worked with the following code

var width2  = jQuery('#cropbox').prop('naturalWidth');
var height2 = jQuery('#cropbox').prop('naturalHeight');

jQuery('#cropbox').Jcrop({
  aspectRatio: 1,
  onSelect: updateCoords,
  onChange: updateCoords,
  setSelec: [0,0,110,110],
  trueSize: [width2,height2]
});
Albania answered 29/9, 2015 at 10:4 Comment(0)
S
1

I hope even my answer would help people to get the idea. Lets say we are having a responsive image in bootstrap with class img-responsive

Here is the html form with image in it

<form method="POST" action="#" enctype="multipart/form-data">
      <img  class="img-responsive" id="get-profile-img" src="image.jpg"/>
      <input id="x" name="x" type="hidden" value="">        
      <input id="y" name="y" type="hidden" value="">        
      <input id="w" name="w" type="hidden" value="">        
      <input id="h" name="h" type="hidden" value="">        

      <input id="rx" name="rx" type="hidden" value="">        
      <input id="ry" name="ry" type="hidden" value="">        
      <input id="rw" name="rw" type="hidden" value="">        
      <input id="rh" name="rh" type="hidden" value="">        
</form>

Here is the JCrop code which will get rx, ry, rw and rh based on calculations of x, y, w and h

$(function() {
    $('#get-profile-img').Jcrop({
            onSelect: updateCoords,
            aspectRatio: 1,
            setSelect  : [50, 0, 300,300],
            allowResize: true
        });
    });
    function updateCoords(c) {
        $('#x').val(c.x);
        $('#y').val(c.y);
        $('#w').val(c.w);
        $('#h').val(c.h);
       responsiveCoords(c, '#get-profile-img');
    };

    function responsiveCoords(c, imgSelector) {

        var imgOrignalWidth     = $(imgSelector).prop('naturalWidth');
        var imgOriginalHeight   = $(imgSelector).prop('naturalHeight');

        var imgResponsiveWidth  = parseInt($(imgSelector).css('width'));
        var imgResponsiveHeight = parseInt($(imgSelector).css('height'));                

        var responsiveX         = Math.ceil((c.x/imgResponsiveWidth) * imgOrignalWidth);
        var responsiveY         = Math.ceil((c.y/imgResponsiveHeight) * imgOriginalHeight);

        var responsiveW         = Math.ceil((c.w/imgResponsiveWidth) * imgOrignalWidth);
        var responsiveH         = Math.ceil((c.h/imgResponsiveHeight) * imgOriginalHeight);

        $('#rx').val(responsiveX);
        $('#ry').val(responsiveY);
        $('#rw').val(responsiveW);
        $('#rh').val(responsiveH);

};

Finally at PHP side take rx, ry, rw and rh instead of x, y, w and h.

(or)

You can simply override the
rx, ry, rw and rh on x, y, w and h like this and use x, y, w and h as usual.

$('#x').val(responsiveX);
$('#y').val(responsiveY);
$('#w').val(responsiveW);
$('#h').val(responsiveH);
Sheepshanks answered 17/7, 2016 at 9:33 Comment(0)
K
0

You can use the truesize parameter for this.

Kittie answered 2/12, 2012 at 22:33 Comment(3)
I don't really understand how I should do this? the responsive image width is something I don't know since it's width:100% on the css.Leroi
You can always ask for the image width/height with javascript.Caudill
It doesn't work like that Jcrop looks for the width in the css by itself.Leroi
A
0

If you load your image with ajax, you can get the image width/height with getimagesize('img.png') and then you can use this variable in your javascript code.

trueSize really worked for me.

Alvinalvina answered 27/5, 2015 at 11:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.