Sometimes it's needed to keep a ratio of an image/canvas but still display it in a middle of a div that might not be the same ratio of the image/canvas, this function returns the new size of the image/canvas to cover the div, with negative margins for top/left if needed.
let myDiv = $('.stage');
let myImage = $('.stage img');
let stage = {
width: myDiv.width(),
height: myDiv.height(),
}
let item = {
width: myImage.width(),
height: myImage.height(),
}
let newItemSize = calculateItemToFitStageButKeepRatio(stage, item);
myImage.css({
width: newItemSize.width,
height: newItemSize.height,
marginTop: newItemSize.marginTop,
marginLeft: newItemSize.marginLeft,
});
function calculateItemToFitStageButKeepRatio(stage, item) {
// Size has to cover so scale item to cover the stage
let stageWidthToItemWidthRatio = stage.width / item.width;
let stageHeightToItemHeightRatio = stage.height / item.height;
// Scale by the largest Ratio
let scaleByRatio = stageWidthToItemWidthRatio > stageHeightToItemHeightRatio ? stageWidthToItemWidthRatio : stageHeightToItemHeightRatio;
let newItemSize = {
width: scaleByRatio * item.width,
height: scaleByRatio * item.height,
marginTop: 0,
marginLeft: 0,
};
let resultMarginTop = 0, resultMarginLeft = 0;
if(newItemSize.width > stage.width) {
newItemSize.marginLeft = ( newItemSize.width - stage.width ) / 2;
}
if(newItemSize.height > stage.height) {
newItemSize.marginTop = ( newItemSize.height - stage.height ) / 2;
}
return newItemSize;
}