Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

object-fit: get resulting dimensions

Tags:

When using the new CSS feature object-fit, how can I access the resulting dimensions that the browser has chosen by JavaScript?

So let's assume foo.jpg is 100x200 pixels. The browser page / viewport is 400px wide and 300px high. Then given this CSS code:

img.foo {   width: 100%;   height: 100%;   object-fit: contain;   object-position: 25% 0; } 

The browser would now show the image on the very top with correct aspect ration stretching to the very bottom on the second quarter from the left. This results in those image dimensions:

  • width: 150px
  • height: 300px
  • left: 62.5px
  • right: 212.5px

So what JavaScript call (jQuery allowed) would give me those numbers that I've calculated manually? (Note: the CSS information themselves are not known by the JavaScript as the user could overwrite them and even add stuff like min-width)

To play with the code I've created a fiddle: https://jsfiddle.net/sydeo244/

like image 947
Chris Avatar asked May 16 '16 14:05

Chris


People also ask

How does object-fit work?

The object-fit CSS property sets how the content of a replaced element, such as an <img> or <video> , should be resized to fit its container. You can alter the alignment of the replaced element's content object within the element's box using the object-position property.

Which of the following are true about the CSS property object-fit '?

contain - The image keeps its aspect ratio, but is resized to fit within the given dimension. cover - The image keeps its aspect ratio and fills the given dimension. The image will be clipped to fit. none - The image is not resized.

Does object-fit work with background image?

Adding a Background to an Image With object-fit: contain # We would benefit from that when also using object-fit: contain . In the example below, we have a grid of images. When the aspect ratios of the image and the container are different, the background color will appear.

Why is object-fit not working in CSS?

For object-fit to work, the image itself needs a width and height . In the OP's CSS, the images do not have width and/or height set, thus object-fit cannot work.


2 Answers

Thanks to @bfred I didn't have to make the initial method.

Here is an extended (and rewritten) version of his, that does calculate the object-position values as well.

function getRenderedSize(contains, cWidth, cHeight, width, height, pos){    var oRatio = width / height,        cRatio = cWidth / cHeight;    return function() {      if (contains ? (oRatio > cRatio) : (oRatio < cRatio)) {        this.width = cWidth;        this.height = cWidth / oRatio;      } else {        this.width = cHeight * oRatio;        this.height = cHeight;      }            this.left = (cWidth - this.width)*(pos/100);      this.right = this.width + this.left;      return this;    }.call({});  }    function getImgSizeInfo(img) {    var pos = window.getComputedStyle(img).getPropertyValue('object-position').split(' ');    return getRenderedSize(true,                           img.width,                           img.height,                           img.naturalWidth,                           img.naturalHeight,                           parseInt(pos[0]));  }    document.querySelector('#foo').addEventListener('load', function(e) {    console.log(getImgSizeInfo(e.target));  });
#container {    width: 400px;    height: 300px;    border: 1px solid blue;  }    #foo {    width: 100%;    height: 100%;    object-fit: contain;    object-position: 25% 0;  }
<div id="container">    <img id="foo" src="http://dummyimage.com/100x200/000/fff.jpg"/>  </div>

Side note

It appears that object-position can have more than 2 values, and when, you need to adjust (or add) which parameter returns the left position value

like image 106
Asons Avatar answered Sep 17 '22 20:09

Asons


There's an npm package called intrinsic-scale that will calculate that for you, but it doesn't support the equivalent of object-position: https://www.npmjs.com/package/intrinsic-scale

This is the whole code:

// adapted from: https://www.npmjs.com/package/intrinsic-scale function getObjectFitSize(contains /* true = contain, false = cover */, containerWidth, containerHeight, width, height){     var doRatio = width / height;     var cRatio = containerWidth / containerHeight;     var targetWidth = 0;     var targetHeight = 0;     var test = contains ? (doRatio > cRatio) : (doRatio < cRatio);      if (test) {         targetWidth = containerWidth;         targetHeight = targetWidth / doRatio;     } else {         targetHeight = containerHeight;         targetWidth = targetHeight * doRatio;     }      return {         width: targetWidth,         height: targetHeight,         x: (containerWidth - targetWidth) / 2,         y: (containerHeight - targetHeight) / 2     }; } 

And the usage would be:

getObjectFitSize(true, img.width, img.height, img.naturalWidth, img.naturalHeight); 
like image 32
fregante Avatar answered Sep 21 '22 20:09

fregante