I know this is a very old question, but the answer I wrote is actually cleaner by using max and mins on the ratios between the images instead of each image with itself:
var originalRatios = {
width: containerWidth / imageNaturalWidth,
height: containerHeight / imageNaturalHeight
};
// formula for cover:
var coverRatio = Math.max(originalRatios.width, originalRatios.height);
// result:
var newImageWidth = imageNaturalWidth * coverRatio;
var newImageHeight = imageNaturalHeight * coverRatio;
I like this approach because it is very systematic — maybe it's the wrong word —. What I mean is you can get rid of the if
statements and make it work in a more "math formula" kind of way (input = output, if that makes sense):
var ratios = {
cover: function(wRatio, hRatio) {
return Math.max(wRatio, hRatio);
},
contain: function(wRatio, hRatio) {
return Math.min(wRatio, hRatio);
},
// original size
"auto": function() {
return 1;
},
// stretch
"100% 100%": function(wRatio, hRatio) {
return { width:wRatio, height:hRatio };
}
};
function getImageSize(options) {
if(!ratios[options.size]) {
throw new Error(options.size + " not found in ratios");
}
var r = ratios[options.size](
options.container.width / options.image.width,
options.container.height / options.image.height
);
return {
width: options.image.width * (r.width || r),
height: options.image.height * (r.height || r)
};
}
Usage
const { width, height } = getImageSize({
container: {width: 100, height: 100},
image: {width: 200, height: 50},
size: 'cover' // 'contain' | 'auto' | '100% 100%'
});
Playground
I created a jsbin
here if you want to take a look at what I mean with systematic (it also has a scale
method that I thought was not needed in this answer but very useful for something other than the usual).
finalHeight = (containerWidth * imgRatio)
to work properly for my code – Kiethkiev