Поворот и масштабирование изображения для "подгонки" контейнера div

Я использую 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>

Ответ 1

Для полноэкранного отображения самое простое решение - использовать единицы просмотра, чтобы указать ширину и высоту изображений:

  • Нормальное изображение должно быть 100vw шириной и 100vh высотой
  • Повернутое изображение должно быть шириной 100vh и высотой 100vh

Изображение может быть перемещено в середину с помощью 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

Сделать высоту элемента равной его ширине и наоборот, это вещь 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>

Ответ 3

Я, вероятно, хотел бы пойти на что-то вроде этого (поменять местами max-width/height с помощью размера окна просмотра)

* {
  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>

Ответ 4

Здесь скудная попытка, которая требует ручной синхронизации ширины/высоты. Для тех, кто желает использовать 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;
}
<div class="top"></div>

Ответ 5

Если вы можете проигнорировать часть преобразования, так как это вопрос соотношения сторон, и на него нет ответа, но отображение 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;
}

Ответ 6

Вы можете сделать это в JavaScript, проверив высоту контейнера и установив maxWidth изображения 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);

Ответ 7

Для части exif вы не можете сделать это с помощью css, поскольку css не может подготовить данные exif.

Для CSS-части вам нужно использовать transform-origin, а не просто transform а также использовать ширину 100% и высоту auto для сохранения соотношения.

Вот пример: http://jsfiddle.net/yxqgt2d1/1/