首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >object-fit:获取结果尺寸

object-fit:获取结果尺寸
EN

Stack Overflow用户
提问于 2016-05-16 22:47:22
回答 4查看 9.4K关注 0票数 22

在使用新的CSS功能object-fit时,如何访问浏览器通过JavaScript选择的结果尺寸?

所以让我们假设foo.jpg是100x200像素。浏览器页面/视口宽400px,高300px。然后给出这段CSS代码:

代码语言:javascript
复制
img.foo {
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: 25% 0;
}

浏览器现在将在最上面显示图像,并将正确的纵横比延伸到从左侧开始的第二个季度的最底部。这会产生这些图像尺寸:

  • 宽度:150px
  • 高度:300px
  • 左:62.5px
  • 右: 212.5px

那么,什么JavaScript调用(允许jQuery)会给出我手动计算的那些数字呢?(注意: JavaScript不知道CSS信息本身,因为用户可以覆盖它们,甚至添加像min-width这样的东西)

为了玩弄代码,我创建了一个小提琴:https://jsfiddle.net/sydeo244/

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2016-05-17 16:26:45

感谢@bfred,我不必创建初始方法。

这是his的一个扩展(重写)版本,它也计算object-position的值。

代码语言:javascript
复制
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));
});
代码语言:javascript
复制
#container {
  width: 400px;
  height: 300px;
  border: 1px solid blue;
}

#foo {
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: 25% 0;
}
代码语言:javascript
复制
<div id="container">
  <img id="foo" src="http://dummyimage.com/100x200/000/fff.jpg"/>
</div>

旁注

看起来object-position可以有两个以上的值,当需要调整(或添加)哪个参数返回左侧位置值时

票数 15
EN

Stack Overflow用户

发布于 2016-05-17 15:11:01

有一个名为intrinsic-scale的npm包将为您计算该值,但它不支持等效的object-positionhttps://www.npmjs.com/package/intrinsic-scale

下面是完整的代码:

代码语言:javascript
复制
// 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
    };
}

它的用法是:

代码语言:javascript
复制
getObjectFitSize(true, img.width, img.height, img.naturalWidth, img.naturalHeight);
票数 9
EN

Stack Overflow用户

发布于 2018-06-19 04:02:26

这里是一个更全面的算法,经过测试,以确定图像在屏幕上的显示方式。

代码语言:javascript
复制
var imageComputedStyle = window.getComputedStyle(image);
var imageObjectFit = imageComputedStyle.getPropertyValue("object-fit");
coordinates = {};
var imagePositions = imageComputedStyle.getPropertyValue("object-position").split(" ");
var horizontalPercentage = parseInt(imagePositions[0]) / 100;
var verticalPercentage = parseInt(imagePositions[1]) / 100;
var naturalRatio = image.naturalWidth / image.naturalHeight;
var visibleRatio = image.width / image.height;
if (imageObjectFit === "none")
{
  coordinates.sourceWidth = image.width;
  coordinates.sourceHeight = image.height;
  coordinates.sourceX = (image.naturalWidth - image.width) * horizontalPercentage;
  coordinates.sourceY = (image.naturalHeight - image.height) * 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 = image.naturalWidth;
  coordinates.sourceHeight = image.naturalHeight;
  coordinates.sourceX = 0;
  coordinates.sourceY = 0;
  if (naturalRatio > visibleRatio)
  {
    coordinates.destinationWidthPercentage = 1;
    coordinates.destinationHeightPercentage = (image.naturalHeight / image.height) / (image.naturalWidth / image.width);
    coordinates.destinationXPercentage = 0;
    coordinates.destinationYPercentage = (1 - coordinates.destinationHeightPercentage) * verticalPercentage;
  }
  else
  {
    coordinates.destinationWidthPercentage = (image.naturalWidth / image.width) / (image.naturalHeight / image.height);
    coordinates.destinationHeightPercentage = 1;
    coordinates.destinationXPercentage = (1 - coordinates.destinationWidthPercentage) * horizontalPercentage;
    coordinates.destinationYPercentage = 0;
  }
}
else if (imageObjectFit === "cover")
{
  if (naturalRatio > visibleRatio)
  {
    coordinates.sourceWidth = image.naturalHeight * visibleRatio;
    coordinates.sourceHeight = image.naturalHeight;
    coordinates.sourceX = (image.naturalWidth - coordinates.sourceWidth) * horizontalPercentage;
    coordinates.sourceY = 0;
  }
  else
  {
    coordinates.sourceWidth = image.naturalWidth;
    coordinates.sourceHeight = image.naturalWidth / visibleRatio;
    coordinates.sourceX = 0;
    coordinates.sourceY = (image.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 = image.naturalWidth;
  coordinates.sourceHeight = image.naturalHeight;
  coordinates.sourceX = 0;
  coordinates.sourceY = 0;
  coordinates.destinationWidthPercentage = 1;
  coordinates.destinationHeightPercentage = 1;
  coordinates.destinationXPercentage = 0;
  coordinates.destinationYPercentage = 0;
}

其中image是HTML <img>元素,coordinates包含以下属性,假设我们认为sourceFrame是完全打印的图像定义的矩形,即它的自然尺寸,printFrame是实际显示的区域,即printFrame.width = image.widthprintFrame.height = image.height

  • sourceX:应该剪切sourceFrame的左上点的水平位置,
    • sourceX:应该剪切sourceFrame的左上点的垂直位置,
    • sourceWidth:应该剪切sourceFrame的多少水平空间,
    • destinationXPercentage:应该剪切多少sourceFrame的垂直空间,
    • destinationXPercentage:将打印图像的printFrame上的左上点的水平位置的百分比,相对于printFrame宽度,
    • destinationWidthPercentage:将打印图像的printFrame上左上点的垂直位置相对于printFrame高度的百分比,
    • destinationWidthPercentage:将在其上打印图像的printFrame宽度相对于printFrame宽度的百分比,
    • destinationWidthPercentage:将在其上打印图像的printFrame高度相对于printFrame高度的百分比。

对不起,scale-down的情况没有处理,因为它的定义不是很清楚。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37256745

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档