Поворот и масштабирование изображения для "подгонки" контейнера 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/