【问题标题】:Rotate and scale image to "fit" container div旋转和缩放图像以“适合”容器 div
【发布时间】:2023-03-16 18:35:01
【问题描述】:

我正在使用transform 根据其 EXIF 数据旋转图像。然后,我想通过使其适合其父 div 来“全屏”显示它。

问题是,max-width / max-height 和所有其他大小调整指令“忽略”旋转(这是正常的,根据 transform 规范,元素的转换在流程中被“忽略”。

Jsfiddle:http://jsfiddle.net/puddjm4y/2/

div.top {
    position: fixed;
    width: 100%;
    height: 100%;
    border: 1px solid blue;
}
img {
    transform: rotate(90deg);
    max-width: 100%;
    max-height: 100%;
}
<div class="top">
    <img src="http://www.androidpolice.com/wp-content/uploads/2014/02/nexusae0_wm_DSC02232.jpg">
</div>

有没有办法做到这一点?

【问题讨论】:

  • 没有什么被忽略,它只是保持图像的纵横比。您示例中的图像已缩放,使其宽度适合父宽度,然后 然后 将其旋转 90 度。图像的高度与包含的宽度完全一样。
  • @meagar 是的,我同意。但我希望它被缩放,以便它的宽度适合父 height 因为它将被旋转。
  • 您的意图是保持照片的纵横比在一侧留下空白,还是完全覆盖容器,裁剪照片以适合,还是完全覆盖照片,丢弃纵横比?
  • @meagar 这是第一个。
  • @Blacksad 你找到答案了吗?我面临着完全相同的问题。我不能让图像完全覆盖它的父级,任何边都没有空格。

标签: html css css-transforms


【解决方案1】:

对于全屏显示,最简单的解决方案是使用视口单位来指定图像的宽度和高度:

  • 普通图像应为 100vw 宽和 100vh 高
  • 旋转后的图像应为 100vh 宽和 100vw 高

可以使用 CSS 转换将图像移动到中间。这是一个例子,它使用了两个比视口更大和更小的图像:

body {
  margin: 0;
}
img {
  display: block;
}
img.normal {
  max-width: 100vw;
  max-height: 100vh;
  transform: translatex(calc(50vw - 50%)) translatey(calc(50vh - 50%));
}
img.rotated {
  max-width: 100vh;
  max-height: 100vw;
  transform: translatex(calc(50vw - 50%)) translatey(calc(50vh - 50%)) rotate(90deg);
}
/* demo */
.demo {
  height: 100vh;
  position: relative;
}
.demo:nth-child(odd) {
  background-color: #CCC;
}
.demo:nth-child(even) {
  background-color: #EEE;
}
.demo::after {
  content: attr(title);
  position: absolute;
  left: 0;
  top: 0;
  padding: .25em .5em;
  background-color: rgba(255, 255, 255, .8);
}
<div class="demo" title="Large image, normal"><img class="normal" src="https://i.stack.imgur.com/2DdPE.jpg"></div>
<div class="demo" title="Large image, rotated"><img class="rotated" src="https://i.stack.imgur.com/2DdPE.jpg"></div>
<div class="demo" title="Small image, normal"><img class="normal" src="https://i.stack.imgur.com/ustNQ.jpg"></div>
<div class="demo" title="Small image, rotated"><img class="rotated" src="https://i.stack.imgur.com/ustNQ.jpg"></div>

【讨论】:

    【解决方案2】:

    我可能会选择这样的东西(使用视口大小交换最大宽度/高度)

    * {
      box-sizing:border-box;
    }
    
    html, body {
      margin:0;
    }
    
    div.top {
        position: fixed;
        width: 100%;
        height: 100%;
        top:0;
        left:0;
        border: 1px solid blue;
        display:flex;
    }
    img {
        transform: rotate(90deg);
        max-width: 100vh;
        max-height: 100vw;
        margin:auto;
    }
    <div class="top">
        <img src="http://www.androidpolice.com/wp-content/uploads/2014/02/nexusae0_wm_DSC02232.jpg">
    </div>

    【讨论】:

    • @Rafael 这无论如何都会以同样的方式工作,position:fixed; 是我相信的某种覆盖框。
    • @MaciejKwas 你确定吗?
    【解决方案3】:

    让一个元素的高度等于它的宽度,反之亦然,这是 Javascript 的事情,因为它可以检索这些值并将它们设置回来。

    在 CSS 中没有办法做到这一点,而且动态尺寸也不可能,我们不知道 100% 到底等于多少,即使我们这样做了,我们也无法使用它们,因为没有参考他们。

    但是,如果您要使用可以通过媒体查询操作的固定值,那么为什么不使用变量,这样我们就有了值和对它的引用。

    :root {
      --width: 100px;
      --height: 140px;
    }
    
    div.top {
      position: fixed;
      width: var(--width);
      height: var(--height);
      border: 1px solid blue;
    }
    
    img {
      width: var(--width);
      height: var(--height);
      animation: rotate 3s alternate infinite;
    }
    
    
    /* translate values are the difference between the height */
    /* and width divided between the X and Y */
    /* 100 - 140 = 40 / 2 = 20px each */
    
    @keyframes rotate {
      to {
        transform: rotate(90deg) translate(20px, 20px);
        width: var(--height);
        height: var(--width);
      }
    }
    <div class="top">
      <img src="http://www.androidpolice.com/wp-content/uploads/2014/02/nexusae0_wm_DSC02232.jpg">
    </div>

    再说一遍,这只是一个想法。

    【讨论】:

    • 你把变换部分复杂化了..不需要复杂的计算,只需这样做transform: rotate(90deg) translateY(-100%); transform-origin: top left;
    • 哦,是的,优化了很多。
    【解决方案4】:

    您可以在 JavaScript 中通过检查容器高度并将图像的 maxWidth 设置为容器的高度来执行此操作。

     /**
     * Set max width of a rotated image to container height
     * @param {*} container
     * @param {*} image
     */
    function setRotatedImageWidth(container = null, image = null) {
        if (!container || !image) {
            return false; // exit if empty
        }
        var h = container.offsetHeight; // Container height
        var w = image.offsetWidth; // Image width
    
        // If image width is greater container height
        if (w > h) {
            image.style.maxWidth = h + 'px';
        }
    }
    
    var container = document.querySelector('.container');
    var image = container.querySelector('img');
    setRotatedImageWidth(container, image);
    

    【讨论】:

      【解决方案5】:

      我终于找到了解决此问题所需的答案,也许它会对其他人有所帮助。 我有一个灵活的父母和我需要根据 EXIF 轮换的孩子。 我需要图像定位:from-image;

      imgBox {
          flex: 1;
          padding: 1rem;
          overflow: hidden;
       }
      
       .img1 {
           object-fit: cover;
           max-width: 100%;
           image-orientation: from-image;
       }
      

      【讨论】:

      • 这帮助我编写了一个为我解决它的函数 - 关键是让容器成为 flexbox,并使用 JS 更改容器的高度以匹配图像横向旋转时的宽度.
      【解决方案6】:

      这是一个需要手动同步宽度 / 高度的尝试。对于那些愿意使用 JS 的人来说,这应该是相当容易同步的。

      这里是:

      div.top {
          border: 1px solid blue;
          box-sizing: border-box;
          width: 100%;
          height: 300px;/* SYNC */
          position: relative;
          overflow: hidden;
      }
      
      div.top:before {
        content: "";
        position: absolute;
        width: 300px;/* SYNC */
        height: 100%; 
        transform: rotate(90deg);
        background-image: url(http://www.androidpolice.com/wp-content/uploads/2014/02/nexusae0_wm_DSC02232.jpg);
        background-size: contain;
        background-repeat: no-repeat;
      }
      &lt;div class="top"&gt;&lt;/div&gt;

      定位变得尴尬。但是,我希望有人会从这里分支并想出一个更好的解决方案。

      【讨论】:

        【解决方案7】:

        如果您可以忽略变换部分,因为它是纵横比的问题并且没有答案,但是可以将图像显示为 100% 的父元素,并且不需要对其进行任何媒体查询。 100% 是相对于父级的,对于图像来说,纵横比决定了尺寸。我们可以拉伸它,但这不会达到目的。希望下面的 css 可以在某种程度上对您有所帮助。

        div.top {
            position: fixed;
            width: 100%;
            height: 100%;
            border: 1px solid blue;
            background-image:url("http://www.androidpolice.com/wp-content/uploads/2014/02/nexusae0_wm_DSC02232.jpg");
            background-size:cover;
            background-repeat:no-repeat;
            background-position:50%;
        }
        div.top img {
            /* transform: rotate(90deg); */
            min-width: 100%;
            min-height: 100%;
            visibility:hidden;
        }
        

        【讨论】:

          【解决方案8】:

          我正在使用图像自然宽度和高度来计算变换比例,正如我在以下位置记录的那样:

          https://stackoverflow.com/a/61620946/7037600

          【讨论】:

            【解决方案9】:

            对于 exif 部分,你不能用 css 来做,因为 css ins 无法准备好 exif 数据。

            但对于 CSS 部分,您需要使用 transform-origin,而不仅仅是 transform,还需要使用宽度 100% 和自动高度来保持比例。

            这是一个例子: http://jsfiddle.net/yxqgt2d1/1/

            【讨论】:

              猜你喜欢
              • 2015-07-14
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2019-11-01
              • 1970-01-01
              • 2019-11-25
              • 1970-01-01
              相关资源
              最近更新 更多