Keeping an images ratio on resize in JavaScript

A little tricky task was given to the team I am working in, to keep an image at its aspect ratio. However the catch is that it needs to be able to go as large as it can to fill the screen at all times, while the user can resize the screen and keeping the images size ratio. Easy you may say, but once you get into it, not so much.

Three of us thought long and hard through many different situation of how we can calculate the size, detect the users actions and calculate the ratio, but with no luck. We also then hunted the internet as all great developers do, which produced many methods using some very long calculation, but none just seemed to work and we knew nothing about the maths.

Then like a shine of light I thought of how you can do it in a simple way. Instead of thinking of the image at 1980px by 1020px and then calculate out the pixel difference etc, you need to think about the image in percentages. When you reduce the images width by say 594 pixel, you would then think of how to calculate the relative pixel difference on the height of the image, but this would be going in the realms of mathematicians. Therefore you stop thinking of that in pixels and think that 1980px reduced by 594px, is a 30% reduction.

Now all you need to do is reduce the height also by 30%, relative to the heights pixels, so here we go…

First we need to find out what the width and heights relative 1% is, so we know where to work from. You need to provide the images original height and width to start this off, then divide each by 100, simple maths.

// Get the one percent of the image width and height
var widthOnePercent = imageOriginWidth / 100;
var heightOnePercent = imageOriginHeight / 100;

Next because we want the image to be as large as it can, we will set the width to be as large as the container to start off the calculations. Once this has been set we can use the images size to find out what percentage the width is at. We know the width of what the image is at in pixels and we know how many pixels are 1%, therefore we can divide the images width by 1%. For example 1386px divided by 19.8px equals 70%.

// Calculate the width percentage
var imageCurrentWidth = $(imageSelector).width();
var imageCurrentPercent = imageCurrentWidth / widthOnePercent;

Now we just need to set the height of the image to 70% of the images height, by multiplying the images 1% height by 70%.

// Calculate the height relative to the percentage of the images width
var imageNewHeight = heightOnePercent * imageCurrentPercent;

However this will work to put the image within the width boundary of the container and the images ratio kept in tact, but potentially due to the width the height could be off the screen. Therefore we need to make sure the image doesn’t go off the screen. This can be calculated out by checking if the height of the image, plus the distance from the top of the window, is not as large as the windows height.

($(window).height() < $(imageSelector).offset().top + imageNewHeight)

Once we have determined this, then we do the same as before but in the opposite direction. This time we start with what height we want the image to be, instead of what height it is. To do this we use the windows height, minus the images top offset, which gives use what space is left.

// Set the new height so it fit on the screen
imageNewHeight = $(window).height() - $(imageSelector).offset().top;

Then the same as before, it is divided by the images 1% height to calculate what the percentage the width is going to be.

// Calculate out what percentage is the height at
imageCurrentPercent = imageNewHeight / heightOnePercent;

// Calculate the width relative to the percentage of the images height
var imageNewWidth = widthOnePercent * imageCurrentPercent;

Below is the full JavaScript code, but to see a full example check out my PureRandom CodePen.

(function($) {

function calIamgeSize(imageSelector, imageOriginWidth, imageOriginHeight) {

// make image as big as it can to start
$(imageSelector).width(
$(imageSelector).parent().width()
);

// Get the one percent of the image width and height
var widthOnePercent = imageOriginWidth / 100;
var heightOnePercent = imageOriginHeight / 100;

// Calculate the width percentage
var imageCurrentWidth = $(imageSelector).width();
var imageCurrentPercent = imageCurrentWidth / widthOnePercent;

// Calculate the height relative to the percentage of the images width
var imageNewHeight = heightOnePercent * imageCurrentPercent;

// If the images height is off the page, then rescale
if ($(window).height() < $(imageSelector).offset().top + imageNewHeight) {

// Set the new height so it fit on the screen
imageNewHeight = $(window).height() - $(imageSelector).offset().top;

// Calculate out what percentage is the height at
imageCurrentPercent = imageNewHeight / heightOnePercent;

// Calculate the width relative to the percentage of the images height
var imageNewWidth = widthOnePercent * imageCurrentPercent;

// Set new width of image
$(imageSelector).width(imageNewWidth);

}

// set new height of image
$(imageSelector).height(imageNewHeight);

}

// Resize image
var imageW = 1000;
var imageH = 667;
var imageClass = ".js-render-image";

$(window).on("resize", function() {

calIamgeSize(imageClass, imageW, imageH);

});

calIamgeSize(imageClass, imageW, imageH);

})($);

Leave a message please

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s