Created
January 24, 2019 13:06
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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