Skip to content

Instantly share code, notes, and snippets.

@ciaranj
Created January 24, 2019 13:06
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save ciaranj/7177fb342102e571db2784dc831f868b to your computer and use it in GitHub Desktop.
Save ciaranj/7177fb342102e571db2784dc831f868b to your computer and use it in GitHub Desktop.
Gist to calculate the properties of an image that has been scaled/positioned through the CSS object-fit and object-position properties
function calculateContainsWindow(image) {
var imageComputedStyle = window.getComputedStyle(image);
var imageObjectFit = imageComputedStyle.getPropertyValue("object-fit");
var coordinates = {};
var imagePositions = imageComputedStyle.getPropertyValue("object-position").split(" ");
var naturalWidth = image.naturalWidth;
var naturalHeight= image.naturalHeight;
if( image.tagName === "VIDEO" ) {
naturalWidth= image.videoWidth;
naturalHeight= image.videoHeight;
}
var horizontalPercentage = parseInt(imagePositions[0]) / 100;
var verticalPercentage = parseInt(imagePositions[1]) / 100;
var naturalRatio = naturalWidth / naturalHeight;
var visibleRatio = image.clientWidth / image.clientHeight;
if (imageObjectFit === "none")
{
coordinates.sourceWidth = image.clientWidth;
coordinates.sourceHeight = image.clientHeight;
coordinates.sourceX = (naturalWidth - image.clientWidth) * horizontalPercentage;
coordinates.sourceY = (naturalHeight - image.clientHeight) * verticalPercentage;
coordinates.destinationWidthPercentage = 1;
coordinates.destinationHeightPercentage = 1;
coordinates.destinationXPercentage = 0;
coordinates.destinationYPercentage = 0;
}
else if (imageObjectFit === "contain" || imageObjectFit === "scale-down")
{
// TODO: handle the "scale-down" appropriately, once its meaning will be clear
coordinates.sourceWidth = naturalWidth;
coordinates.sourceHeight = naturalHeight;
coordinates.sourceX = 0;
coordinates.sourceY = 0;
if (naturalRatio > visibleRatio)
{
coordinates.destinationWidthPercentage = 1;
coordinates.destinationHeightPercentage = (naturalHeight / image.clientHeight) / (naturalWidth / image.clientWidth);
coordinates.destinationXPercentage = 0;
coordinates.destinationYPercentage = (1 - coordinates.destinationHeightPercentage) * verticalPercentage;
}
else
{
coordinates.destinationWidthPercentage = (naturalWidth / image.clientWidth) / (naturalHeight / image.clientHeight);
coordinates.destinationHeightPercentage = 1;
coordinates.destinationXPercentage = (1 - coordinates.destinationWidthPercentage) * horizontalPercentage;
coordinates.destinationYPercentage = 0;
}
}
else if (imageObjectFit === "cover")
{
if (naturalRatio > visibleRatio)
{
coordinates.sourceWidth = naturalHeight * visibleRatio;
coordinates.sourceHeight = naturalHeight;
coordinates.sourceX = (naturalWidth - coordinates.sourceWidth) * horizontalPercentage;
coordinates.sourceY = 0;
}
else
{
coordinates.sourceWidth = naturalWidth;
coordinates.sourceHeight = naturalWidth / visibleRatio;
coordinates.sourceX = 0;
coordinates.sourceY = (naturalHeight - coordinates.sourceHeight) * verticalPercentage;
}
coordinates.destinationWidthPercentage = 1;
coordinates.destinationHeightPercentage = 1;
coordinates.destinationXPercentage = 0;
coordinates.destinationYPercentage = 0;
}
else
{
if (imageObjectFit !== "fill")
{
console.error("unexpected 'object-fit' attribute with value '" + imageObjectFit + "' relative to");
}
coordinates.sourceWidth = naturalWidth;
coordinates.sourceHeight = naturalHeight;
coordinates.sourceX = 0;
coordinates.sourceY = 0;
coordinates.destinationWidthPercentage = 1;
coordinates.destinationHeightPercentage = 1;
coordinates.destinationXPercentage = 0;
coordinates.destinationYPercentage = 0;
}
return coordinates;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment