saginadir
9/12/2016 - 7:31 AM

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 i

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;
}