2016-05-16 2 views
6

При использовании новой функции CSS object-fit, как я могу получить доступ к результирующим параметрам, выбранным браузером JavaScript?object-fit: получить полученные размеры

Итак, допустим, foo.jpg - 100x200 пикселей. Страница браузера/видового экрана имеет ширину 400 пикселей и высоту 300 пикселей. Затем дал этот CSS код:

img.foo { 
    width: 100%; 
    height: 100%; 
    object-fit: contain; 
    object-position: 25% 0; 
} 

Браузер теперь будет показывать изображение на самом верху с правильным соотношение сторон простирается до самого дна на второй квартал слева. Это приводит к тем размеры изображения:

  • ширина: 150px
  • высота: 300px
  • слева 62.5px
  • право: 212.5px

Так что JavaScript вызов (JQuery разрешено) давал бы мне те числа, которые я вычислил вручную? (Примечание: информация CSS сами не известны на JavaScript, поскольку пользователь может переписать их и даже добавить такие вещи, как min-width)

Чтобы играть с кодом, я создал скрипку: https://jsfiddle.net/sydeo244/

+0

если вы используете '$ ('img.foo'). outerWidth()' вы получите общую расчетную ширину элементов т. Непонятно, что вы спрашиваете –

+0

Нет, 'outerWidth()' в этом случае не работает, так как это приведет к ширине «полного» изображения, поэтому оно вернет '400' из-за' width: 100% 'а не' 150' по желанию. – Chris

+0

Не существует специального свойства, которое даст вам это значение, вам нужно использовать сгенерированный размер элемента 'img', а затем использовать свойства' naturalWidth'/'naturalHeight', чтобы получить его соотношение сторон, а затем вычислить его рендеринг размер (почти такой же вы сделали вручную). – LGSon

ответ

2

Благодаря @bfred у меня не было, чтобы сделать первоначальный метод.

Это расширенная (и переписанная) версия его, которая также вычисляет значения object-position.

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)); 
 
});
#container { 
 
    width: 400px; 
 
    height: 300px; 
 
    border: 1px solid blue; 
 
} 
 

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

Примечание стороны

Оказывается, что object-position может иметь более 2 значения, и, когда вам нужно настроить (или добавить), который параметр возвращает левое положение значение

+0

Ручное «сжатие» делает код менее читаемым; пусть uglifyjs выполняет грязную работу только для браузера.В действительности, uglifyjs сжимает внутренний код больше, чем сжатый вручную. (146 байт против 179 байт) –

+0

@ bfred.it Согласен с вами в этом ... «несжатый» это немного :) – LGSon

+0

Спасибо, я надеялся, что есть API, который был скрыт от меня. Но ответчики ясно, что его нет (еще?). Поскольку ваш ответ выполняет задание, он правильный, и поэтому я принял его. – Chris

1

Там в NPM пакет под названием intrinsic-scale, который рассчитает, что для вас, но он не поддерживает эквивалент object-position: https://www.npmjs.com/package/intrinsic-scale

Это весь код:

// 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 
    }; 
} 

И использование будет:

getObjectFitSize(true, img.width, img.height, img.naturalWidth, img.naturalHeight); 
Смежные вопросы