1

There is nice css trick to always position image in the center of div regardless of image size or aspect ratio.

<style>
.img_wrap {
    padding-bottom: 56.25%;
    width: 100%; 
    position: relative;
    overflow: hidden;
}
#imgpreview {
    display: block;
    max-height: 100%;
    max-width: 100%;
    width: auto;
    height: auto;
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    margin: auto;
}
</style>
<div class="img_wrap">
  <img id="imgpreview" src="http://i.imgur.com/RRUe0Mo.png" alt="your image" />
</div>

Then I added jquery code for rotating image

$(document).ready(function(){
    var rotation = 0;

    jQuery.fn.rotate = function(degrees) {
        $(this).css({'-webkit-transform' : 'rotate('+ degrees +'deg)',
                     '-moz-transform' : 'rotate('+ degrees +'deg)',
                     '-ms-transform' : 'rotate('+ degrees +'deg)',
                     'transform' : 'rotate('+ degrees +'deg)'});
    };

    $('#imgpreview').click(function() {
        rotation += 90;
        $(this).rotate(rotation);
        // $(this).toggleClass("imgpreview");
    });
});

However, when I am rotation image, it gets cropped. I want to avoid that.

I tried to play with addClass feature but with no success. If someone could suggest any solution would appreciate a lot.

I have created jsfidlle for this question. Here the updated fiddle

3
  • remove overflow: hidden; from the .img-wrap and it will not crop Commented Nov 23, 2016 at 9:36
  • Sorry, I have not properly explained the question. What I meant is that I want the rotated image to take img_wrap size. In this case the original picture is landscape oriented so on rotating for 90 degrees I want it to "shrink" in width so that the width would take the value of img_wrap height. Commented Nov 23, 2016 at 9:46
  • note that img_wrap has zero height - any height it has is from the padding-bottom Commented Nov 23, 2016 at 9:47

3 Answers 3

1

So this is what I did to your code:

  1. Removed the overflow: hidden for img_wrap.

  2. In JS I did this:

      $('.imgpreview').click(function() {
        rotation += 90;
        rotation %= 360;
        $(this).rotate(rotation);
    
        // when rotation is 90 or 270
        if ((rotation / 90) & 1) {
          $(this).css({
            'width': $('.img_wrap').innerHeight(),
            'max-height': $('.img_wrap').innerWidth()
          });
        } else {
          $(this).css({
            'width': 'auto',
            'max-height': '100%'
          });
        }
      });
    
  3. Note that the width/height calculations are done after the call to rotate function. After rotation, width is height and vice-versa for the imgpreview and so we have to allow height to adjust while setting width of imgpreview - hence the max-height style adjustment.

See demo below:

$(document).ready(function() {
  var rotation = 0;

  jQuery.fn.rotate = function(degrees) {
    $(this).css({
      '-webkit-transform': 'rotate(' + degrees + 'deg)',
      '-moz-transform': 'rotate(' + degrees + 'deg)',
      '-ms-transform': 'rotate(' + degrees + 'deg)',
      'transform': 'rotate(' + degrees + 'deg)'
    });
  };

  $('.imgpreview').click(function() {
    rotation += 90;
    rotation %= 360;
    $(this).rotate(rotation);

    // when rotation is 90 or 270
    if ((rotation / 90) & 1) {
      $(this).css({
        'width': $('.img_wrap').innerHeight(),
        'max-height': $('.img_wrap').innerWidth()
      });
    } else {
      $(this).css({
        'width': 'auto',
        'max-height': '100%'
      });
    }
  });
});
body {
  margin: 0;
}
.img_wrap {
  width: 100%;
  position: relative;
  border: 3px solid black;
  padding-bottom: 56.25%;
  /*overflow: hidden;*/
}
.imgpreview {
  display: block;
  max-height: 100%;
  max-width: 100%;
  width: auto;
  height: auto;
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  margin: auto;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


<div class="img_wrap" id="P">
  <img class="imgpreview" id="Pim" src="https://3.bp.blogspot.com/-W__wiaHUjwI/Vt3Grd8df0I/AAAAAAAAA78/7xqUNj8ujtY/s1600/image02.png" alt="your image" />
</div>
<br/>
<div class="img_wrap">
  <img class="imgpreview" src="http://i.imgur.com/RRUe0Mo.png" alt="your image" />
</div>

Sign up to request clarification or add additional context in comments.

9 Comments

While this is a great implementation it does not work for me. The wrapper is inside BS modal. If using vh then image goes outside the modal. I have updated the fidlle with my solution - the trick is to use innerHeigt() instead of heigt(). Could I ask you what is the purpose of this line rotation %= 360; in your code?
of course, I set 100vh just for illustration... rotation%=360 ensures that the variable rotation will always range from 0 upto 360
you can replace 100vh in img_wrap css and in the JS code to the value of the height of the container, does that sound good?
Yes it seems to be ok, but I have another problem now. Here is updated fiddle. Problem is that this trick does not work for portrait oriented images.
I didn't get your issue - you are using jquery toggle on clicking the toggle landscape button? I'm confused....
|
1

You can achieve this with jquery by altering a little bit your code:

$('#imgpreview').click(function() {
    if (rotation === 360) {
        rotation = 0
    } else {
        rotation += 90;
    }
    $(this).rotate(rotation);
    if(rotation === 90 || rotation === 270) {
        $('.img_wrap').css('height', $(this).width());
    } else {
        $('.img_wrap').css('height', 'auto');
    }
});

There's maybe the need to alter your css also but it depends what is the end result that you wish to have.

2 Comments

Thank you for your answer, it was realy useful. I have upadated the fiddle with end result!
Glad I helped :) Some acceptance and upvoting would be awesome ;)
1

There are many ways to do that.
The jQuery below is determine whether it is vertical or not.
You just need to add this line into your function(degrees)

((degrees/90) == 1 || (degrees/90) == 3)? $(this).css('width','56.25%'):$(this).css('width','auto');

Jsfiddle

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.