【问题标题】:scale image to fit its parent object proportionally缩放图像以按比例适合其父对象
【发布时间】:2015-11-16 01:03:29
【问题描述】:

Irealisethishasbeenaskedmanymanytimesundermany@9876543331@,但大多数解决方案似乎并不关心生成的高度。或仅在一个方向上缩放。这个:

min-width: 100%;
height: auto;

不是解决方案。

我正在尝试使图像适应高度和宽度,以便可以将其动态注入到不同系统和站点中的多个位置,因此我不一定知道父对象将是什么 -可能是带有或不带有溢出集的 div,或者是 p,或者是 body - 或者它的尺寸;父容器不能仅仅通过注入我的图像/脚本来改变大小。jQuery 不可用。

我看不出 css3 后台技术是如何工作的。

按比例缩放就像使用比率一样简单:

<img onload="scale(this)" src="screenshot.png">
<script type="text/javascript">
function scale(img){
var p = img.parentNode,
    x = p.offsetWidth,
    y = p.offsetHeight,
    w = img.naturalWidth,
    h = img.naturalHeight;
    ratio = h / w;
    if (h >= y) {
        h = y;
        w = h / ratio;
        img.style.width = w + "px";
        img.style.height = h + "px";
    } else if(w >= x) {  //} && ratio <= 1){
        w = x;
        h = w * ratio;
        img.style.width = w + "px";
        img.style.height = h + "px";
    }
}
</script>

但这只能在一个平面上缩放 - 我需要它继续缩放宽度和高度,直到它在两个维度上都整齐地适合父容器空间。如果图像小于父容器,则应按比例放大以填充。

【问题讨论】:

  • 如果图像是 800x600(水平)并且父级是 200x800(垂直)怎么办?
  • 你是说background-size:contain; 不是你要找的吗?
  • 除非容器与图片的纵横比完全相同,否则您将获得可怕的伪影和沿一个轴的拉伸/压缩,或者您将不得不使用信箱或柱子。
  • 之所以只设置一个维度,是为了保证成比例。

标签: javascript


【解决方案1】:

在不拉伸图像的情况下调整图像以适应父容器(大小未知)


让 CSS 完成这项工作,而不是与 JS 混在一起!
  • 将图片设置为100%;高度和宽度;
  • 将图片的src 替换为透明像素,并将其背景设置为实际的src
  • 在您的(现在)全尺寸图片上使用 CSS 的 background-size

contain(图像将完全覆盖父级)
cover(图像将遵循图像比例)

使用contain 的示例

function scale( img ) {
  if(img.isScaled) return;
  img.style.background="no-repeat url("+ img.src +") 50%";
  img.style.backgroundSize="contain";  // Use "contain", "cover" or a % value
  img.style.width="100%";
  img.style.height="100%";
  img.isScaled=true; // Prevent triggering another onload on src change
  img.src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
}
<div style="width:300px; height:300px; background:#000; margin:10px;">
  <img onload="scale(this);" src="//placehold.it/1200x600/f0f">
</div>


<div style="width:300px; height:300px; background:#000; margin:10px;">
  <img onload="scale(this);" src="//placehold.it/400x600/cf5">
</div>

测试于:FF、CH、E、IE(11)、SA


注意:透明像素数据仅用于防止浏览器的Missing Iimage Icon否则是因为做img.src = "";

http://caniuse.com/#search=background-size

【讨论】:

  • @RokoC.Bujan 图片是display: inline-block 还是block 有关系吗?
  • @zer00ne 没关系。如果以上内容适用于inline(默认)图像,为什么block 会改变任何东西?
  • @RokoC.Bujan 在更严格的标准下统一浏览器之前,我认为没有什么是理所当然的。我不确定block 是否有所作为,但我确实记得inlineinline-block 处理高度的方式与block 不同。感谢您提供这种轻巧简单的解决方案。
  • @zer00ne 不客气 ;) 我已经在 Ch、Ff、Sa、E、IE11(模拟 IE8 和 IE7)中测试了上述内容。
【解决方案2】:

我使用此代码使视频适合其父级:

      var parent = vid.parentNode,
      vw = vid.videoWidth,
      vh = vid.videoHeight,
      vr = vh / vw, // video ratio
      pw = parent.offsetWidth,
      ph = parent.offsetHeight,
      pr = ph / pw; // parent ratio
      if(pr > vr) {
        vid.style.width = 'unset';
        vid.style.height = `${ph}px`;
      } else {
        vid.style.height = 'unset';
        vid.style.width = `${pw}px`;
      }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-26
    • 1970-01-01
    • 2020-12-20
    • 1970-01-01
    • 2014-06-08
    • 2013-11-05
    • 2022-10-06
    相关资源
    最近更新 更多