RoR: jQuery jCrop, not properly cropping in preview

1k Views Asked by At

I'm not getting proper cropping in my preview, and also, when I save the cropping image, it doesn't really crop the image.

When I'm trying to drag the cropping window, it stretches my image, and my image doesn't stay in one place, it'll move around

out of window cropping This shows that the preview image is out of preview window.

enter image description here This shows that my preview image is being stretched.

Here is my user.js.coffee

jQuery(document).ready ($) ->
  jQuery ->
    new PicCropper()

  class PicCropper
    constructor: ->
      $('#cropbox').Jcrop
        aspectRatio: 1
        setSelect: [0, 0, 500, 500]
        onSelect: @update 
        onChange: @update

    update: (coords) =>
      $('#user_crop_x').val(coords.x)
      $('#user_crop_y').val(coords.y)
      $('#user_crop_w').val(coords.w)
      $('#user_crop_h').val(coords.h)
      @updatePreview(coords)

    updatePreview: (coords) =>
      $('#preview').css
        width: Math.round(100/coords.w * $('#cropbox').width()) + 'px'
        height: Math.round(100/coords.h * $('#cropbox').height()) + 'px'  
        marginLeft: '-' + Math.round(100/coords.w * coords.x) + 'px'
        marginTop: '-' + Math.round(100/coords.h * coords.y) + 'px'

Here's my users_controller

  def update
    if params[:user][:password].blank?
      [:password,:password_confirmation,:current_password].collect{|p| params[:user].delete(p) }
    else
      @user.errors[:base] << "The password you entered is incorrect" unless @user.valid_password?(params[:user][:current_password])
    end

    @user = User.find(params[:id])
    if @user.update_attributes(params[:user])
      if params[:user][:profile_pic].present?
        render :crop
      else
        redirect_to @user, notice: "Successfully updated image."
      end
    else
      render :action => 'edit'
    end

Can anyone pinpoint why I'm getting this?

Thanks

4

There are 4 best solutions below

0
On

Checkout the new JCrop version https://github.com/maxd/jcrop-rails-v2

0
On

Your dimensions seem wrong: You should consider variable dimensions images so, I suggest you Study this jquery example it may be helpfull to you (I hope)

It does it dynamicaly

JS

    jQuery(function ($) {
        $('.aDimension').each(function () {
            var jcrop_api,
                boundx,
                boundy,
            //updateable coords
                coordX = 0,
                coordY = 0,
                coordH = 0,
                coordW = 0,

            //preset
                currentWidth = $(this).find('.dimensionedAvatar').attr('w'),
                currentHeight = $(this).find('.dimensionedAvatar').attr('h'),

                $loading = $(this).find('.loading'),
                $complete = $(this).find('.complete'),
                $cropItNow = $(this).find('.cropItNow'),
                $controlsPane = $(this).find('.controls-pane'),

            // Grab some information about the preview pane
            $preview = $('#dimensionedAvatar' + currentHeight + '_' + currentWidth),
                $pcnt = $('#dimensionedAvatar' + currentHeight + '_' + currentWidth + ' .preview-container'),
                $pimg = $('#dimensionedAvatar' + currentHeight + '_' + currentWidth + ' .preview-container img'),
                xsize = $pcnt.width(),
                ysize = $pcnt.height();


            $complete.hide();
            $loading.hide();
            $cropItNow.click(function (e) {
                //alert("(" + coordX + "," + coordY + "," + coordH + "," + coordW + ")");

                var cropingUrl = '/Event/CropAvatar' + "/51?x=" + coordX + "&y=" + coordY + "&h=" + coordH + "&w=" + coordW + "&toh=" + currentHeight + "&tow=" + currentWidth;
                $loading.show();
                //alert(cropingUrl);
                $.getJSON(cropingUrl, {}, function (_result) {
                    $loading.hide();
                    $complete.html("Miniature Sauvegardée").show();
                }).fail(function (err) {
                    alert(err);
                });
            });


            //console.log('init',[xsize,ysize]);
            $('#avatarImgContainer' + currentHeight + '_' + currentWidth + ' img').Jcrop({
                onChange: updatePreview,
                onSelect: updatePreview,
                aspectRatio: parseFloat('') > 0 ? parseFloat('') : xsize / ysize
            }, function () {
                // Use the API to get the real image size
                var bounds = this.getBounds();
                boundx = bounds[0];
                boundy = bounds[1];
                // Store the API in the jcrop_api variable
                jcrop_api = this;

                // Move the preview into the jcrop container for css positioning
                // $preview.appendTo(jcrop_api.ui.holder);
            });

            function updatePreview(c) {

                coordX = parseInt(c.x);
                coordY = parseInt(c.y);
                coordH = parseInt(c.h);
                coordW = parseInt(c.w);

                if (parseInt(c.w) > 0) {
                    var rx = xsize / c.w;
                    var ry = ysize / c.h;

                    $pimg.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'
                    });
                }
            };
        });
    });

HTML

 <fieldset class="fieldset aDimension">
        <legend>Dimension
            252-420</legend>
        <div id="avatarImgContainer252_420" class="left" style="width: 450px;
            height: 260px; margin: 0 4px 14px; padding: 1px; overflow: auto; background: #efefef;
            border: 1px solid #ccf;position: relative;">
            <img src="/uploads/avatars/events/51.png" 
            id="Img1" alt="chargement en cours..." />
        </div>
        <div id="dimensionedAvatar252_420" class="dimensionedAvatar left"
            h="252" w="420" 
            style="display: block; position: relative;z-index: 2000;
            /*top: 10px;right: -280px;*/padding: 6px;border: 1px rgba(0,0,0,.4) solid;background-color: white;
            -webkit-border-radius: 6px;-moz-border-radius: 6px;border-radius: 6px;
            -webkit-box-shadow: 1px 1px 5px 2px rgba(0, 0, 0, 0.2);
            -moz-box-shadow: 1px 1px 5px 2px rgba(0, 0, 0, 0.2);
            box-shadow: 1px 1px 5px 2px rgba(0, 0, 0, 0.2);">
            <div class="left preview-container" style="margin: 4px; width: 420px; height: 252px;
                border: 1px solid #ccc; overflow: hidden;">
                <img class="preview" src="/uploads/avatars/events/51.png"
                    alt="img" />
            </div>
            <div class="left controls-pane">
                <input type="button" value="Rogner" class="button cropItNow" />
                <div class="loading">
                    en cours...</div>
                <div class="complete">
                    fait!</div>
            </div>
            <div class="clear">
            </div>
        </div>
        <!--AvatardDimension-->
    </fieldset>
    <div class="clear">
    </div>

    <fieldset class="fieldset aDimension">
        <legend>Dimension
            60-88</legend>
        <div id="avatarImgContainer60_88" class="left" style="width: 450px;
            height: 260px; margin: 0 4px 14px; padding: 1px; overflow: auto; background: #efefef;
            border: 1px solid #ccf;position: relative;">
            <img src="/uploads/avatars/events/51.png" 
            id="Img1" alt="chargement en cours..." />
        </div>
        <div id="dimensionedAvatar60_88" class="dimensionedAvatar left"
            h="60" w="88" 
            style="display: block; position: relative;z-index: 2000;
            /*top: 10px;right: -280px;*/padding: 6px;border: 1px rgba(0,0,0,.4) solid;background-color: white;
            -webkit-border-radius: 6px;-moz-border-radius: 6px;border-radius: 6px;
            -webkit-box-shadow: 1px 1px 5px 2px rgba(0, 0, 0, 0.2);
            -moz-box-shadow: 1px 1px 5px 2px rgba(0, 0, 0, 0.2);
            box-shadow: 1px 1px 5px 2px rgba(0, 0, 0, 0.2);">
            <div class="left preview-container" style="margin: 4px; width: 88px; height: 60px;
                border: 1px solid #ccc; overflow: hidden;">
                <img class="preview" src="/uploads/avatars/events/51.png"
                    alt="img" />
            </div>
            <div class="left controls-pane">
                <input type="button" value="Rogner" class="button cropItNow" />
                <div class="loading">
                    en cours...</div>
                <div class="complete">
                    fait!</div>
            </div>
            <div class="clear">
            </div>
        </div>
        <!--AvatardDimension-->
    </fieldset>
    <div class="clear">
    </div>

    <fieldset class="fieldset aDimension">
        <legend>Dimension
            68-152</legend>
        <div id="avatarImgContainer68_152" class="left" style="width: 450px;
            height: 260px; margin: 0 4px 14px; padding: 1px; overflow: auto; background: #efefef;
            border: 1px solid #ccf;position: relative;">
            <img src="/uploads/avatars/events/51.png" 
            id="Img1" alt="chargement en cours..." />
        </div>
        <div id="dimensionedAvatar68_152" class="dimensionedAvatar left"
            h="68" w="152" 
            style="display: block; position: relative;z-index: 2000;
            /*top: 10px;right: -280px;*/padding: 6px;border: 1px rgba(0,0,0,.4) solid;background-color: white;
            -webkit-border-radius: 6px;-moz-border-radius: 6px;border-radius: 6px;
            -webkit-box-shadow: 1px 1px 5px 2px rgba(0, 0, 0, 0.2);
            -moz-box-shadow: 1px 1px 5px 2px rgba(0, 0, 0, 0.2);
            box-shadow: 1px 1px 5px 2px rgba(0, 0, 0, 0.2);">
            <div class="left preview-container" style="margin: 4px; width: 152px; height: 68px;
                border: 1px solid #ccc; overflow: hidden;">
                <img class="preview" src="/uploads/avatars/events/51.png"
                    alt="img" />
            </div>
            <div class="left controls-pane">
                <input type="button" value="Rogner" class="button cropItNow" />
                <div class="loading">
                    en cours...</div>
                <div class="complete">
                    fait!</div>
            </div>
            <div class="clear">
            </div>
        </div>
        <!--AvatardDimension-->
    </fieldset>
1
On

The issue was because I needed to hard code in the CSS style and make the preview image width and height to 0

0
On

if you are using bootstrap you have to add

img.jcrop {max-width: none}

for your css.. somehow bootstrap is overriding img {max-width:100%}

for more information checkout https://github.com/twbs/bootstrap/issues/1649