Gerico
Gerico

Reputation: 5169

jQuery change image height keep aspect ratio

Image in a container div, with the height issue

So i have a gallery where most my images are currently controlled 100% by CSS. However, in setting min-height: 100%; on my images, i cause some to stretch. I don't have too many problematic photos, but it's out of my control what the user will upload.

Is there anyway with jQuery i can get image height and check if it's meeting a requirement, and if not, somehow increase the image width in order to meet the height requirement but keep things all in ratio? So i therefore avoid causing any distortion but keep the gallery neat by having divs without gaps.

Note: The image provided is what happens when i remove my min-height: 100%; so that you can see my issue.

Update - - - - -

I found a solution that seems to work ok for the moment, it might not be the best attempt but i found another answer that helped me: How to resize images proportionally / keeping the aspect ratio?

I simply tweaked the code ever so slightly, now if an image doesn't meet the minHeight required it will resize the image in proportion so until the minHeight is then reached. Seems work fine for me in testing.

**Update Final ********* After playing around i took a small snippit from the thumb script, just the part where it absolutely positions the images within the container.

$(window).load(function() {

    $('.thumbnail img').each(function() {
        var maxWidth = 320; // Max width for the image
        var minHeight = 270;    // Max height for the image
        var ratio = 0;  // Used for aspect ratio
        var width = $(this).width();    // Current image width
        var height = $(this).height();  // Current image height

        if(width > maxWidth){
            ratio = maxWidth / width;   // get ratio for scaling image
            $(this).css("width", maxWidth); // Set new width
            $(this).css("height", height * ratio);  // Scale height based on ratio
            height = height * ratio;    // Reset height to match scaled image
            width = width * ratio;    // Reset width to match scaled image
        }

        // Check if current height is larger than max
        if(height < minHeight){
            ratio = minHeight / height; // get ratio for scaling image
            $(this).css("height", minHeight);   // Set new height
            $(this).css("width", width * ratio);    // Scale width based on ratio
            width = width * ratio;    // Reset width to match scaled image
        }

        var $img = $(this),
        css = {
            position: 'absolute',
            marginLeft: '-' + ( parseInt( $img.css('width') ) / 2 ) + 'px',
            left: '50%',
            top: '50%',
            marginTop: '-' + ( parseInt( $img.css('height') ) / 2 ) + 'px'
        };

        $img.css( css );
   });

});

This loops through all my thumbnails, resizes them accordingly. So if the minimum height is not met, the image will be scaled up until the height fits my thumbnail container. Then the bottom part will take take each image, absolutely position it, and take the width and height and divide by 2, in order to work out how much to minus off on the margins to center the image. I'm still tweaking this, but seems to work well for me at the moment. I hope this helps someone else.

Alternatively

Anyone with a similar issue i found this: http://joanpiedra.com/jquery/thumbs/ I had begun writing my own to do exactly this, but im going to look into how well this works and adapt it as needed.

Upvotes: 7

Views: 28181

Answers (4)

Gerico
Gerico

Reputation: 5169

I found a solution that seems to work ok for the moment, it might not be the best attempt but i found another answer that helped me: How to resize images proportionally / keeping the aspect ratio?

Updated question with my findings

$(window).load(function() {
    $('.image-gallery-item-image-link img').each(function() {
        var maxWidth = 320; // Max width for the image
        var minHeight = 270;    // Max height for the image
        var ratio = 0;  // Used for aspect ratio
        var width = $(this).width();    // Current image width
        var height = $(this).height();  // Current image height

        if(width > maxWidth){
            ratio = maxWidth / width;   // get ratio for scaling image
            $(this).css("width", maxWidth); // Set new width
            $(this).css("height", height * ratio);  // Scale height based on ratio
            height = height * ratio;    // Reset height to match scaled image
            width = width * ratio;    // Reset width to match scaled image
        }

        // Check if current height is larger than max
        if(height < minHeight){
            ratio = minHeight / height; // get ratio for scaling image
            $(this).css("height", minHeight);   // Set new height
            $(this).css("width", width * ratio);    // Scale width based on ratio
            width = width * ratio;    // Reset width to match scaled image
        }

        var $img = $(this),
        css = {
            position: 'absolute',
            marginLeft: '-' + ( parseInt( $img.css('width') ) / 2 ) + 'px',
            left: '50%',
            top: '50%',
            marginTop: '-' + ( parseInt( $img.css('height') ) / 2 ) + 'px'
        };

        $img.css( css );
   });
});

Upvotes: 5

Todd
Todd

Reputation: 5454

So, I realize this question asked a while ago. But I've since found a sweet css only way to maintain the aspect ratio of an element, fluidly. Try it out:

#targetElement {
    max-width: 100%;
}

#targetElement:after {
    content: '';
    width: 100%;
    padding-bottom: <aspect-ratio>%; // where (height / width)*100 = <aspect-ratio>
}

Yeah, so I use this trick all the time now, and it's definitely more performant and less verbose than using javascript, or even less efficient, JQuery. Hope this helps somebody somewhere! If you're a LESS person, I have a mixin Gist on Github that does this -- that's how often I use it! It lives here: Sweet AR trick.

Upvotes: 0

Todd
Todd

Reputation: 5454

well, if keeping the entire picture visible isn't necessary(e.g. thumbnails in a gallery), you could accomplish this with css only. it seems you have landscape type photos. html

<div class="img-container">
<img src="path/to/img.png" alt="">
</div>

css:

div > img {
background-repeat: no-repeat;
background-position: center center;
background-attachment: fixed;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
width:100%;
height:100%;

}

jquery:
$(document).ready(function(){
     $(".imgcontainer > img").each(function(){
       var thisimg = "url("+$(this).attr('src')+")";
       $(this).css({'background-image': thisimg });
       $(this).attr('src', '');
     });

}); 

Upvotes: 3

codeVerine
codeVerine

Reputation: 762

Whose aspect ratio you are talking about ? aspect ratio of your gallery or the aspect ratio of the image ? You can't keep an image in correct aspect ratio by changing one dimension only (here height). In order to keep aspect ratio, you must change both the height and width of the image. Any way if you want try this :

var img = document.getElementById('imageid'); 
var width = img.clientWidth;
var height = img.clientHeight;
if(width >height)
    $(img).attr('style',"width=100%");
else
    $(img).attr('style',"height=100%");

What I am trying to do is that, set the css of the largest dimension to 100%. It'll do the trick.

Upvotes: 1

Related Questions