2016-05-16 7 views
6

Wie kann ich mit der neuen CSS-Funktion object-fit auf die resultierenden Dimensionen zugreifen, die der Browser mit JavaScript ausgewählt hat?object-fit: Erhalten Sie die resultierenden Dimensionen

Nehmen wir an, foo.jpg ist 100x200 Pixel. Die Browserseite/das Ansichtsfenster ist 400 Pixel breit und 300 Pixel hoch. Dann diesen CSS-Code angegeben:

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

Der Browser nun das Bild auf dem ganz oben mit dem richtigen Seitenverhältnis Dehnung bis auf den Grund im zweiten Quartal von der linken Seite zeigen würde. Dies führt in den Bildabmessungen:

  • width: 150px
  • Höhe: 300px
  • links: 62.5px
  • rechts: 212.5px

Was Aufruf JavaScript (jQuery erlaubt) würde mir die Zahlen geben, die ich manuell berechnet habe? (Hinweis: Die CSS-Informationen nicht selbst mit dem JavaScript bekannt sind, wie der Benutzer sie überschreiben könnte und sogar Sachen wie min-width hinzufügen)

mit dem Code zu spielen, ich eine Geige erstellt haben: https://jsfiddle.net/sydeo244/

+0

Wenn Sie '$ ('img.foo'). outerWidth()' verwenden, erhalten Sie die gesamte berechnete Breite des Elemen t. Nicht klar, was Sie fragen –

+0

Nein, 'outerWidth()' funktioniert in diesem Fall nicht, da es die Breite des "vollen" Bildes ergibt - also würde es '400' zurückgeben wegen der' width: 100% 'und nicht' 150' wie gewünscht. – Chris

+0

Es gibt keine spezielle Eigenschaft, die Ihnen diesen Wert gibt, Sie müssen die generierte Größe des Elements 'img' verwenden und dann die Eigenschaften' naturalWidth'/'naturalHeight' verwenden, um das Seitenverhältnis zu erhalten und dann das gerenderte zu berechnen Größe (ziemlich genau dasselbe, was Sie manuell getan haben). – LGSon

Antwort

2

Dank @bfred ich habe nicht die ursprüngliche Methode zu machen.

Hier ist eine erweiterte (und neu geschriebene) Version von ihm, die auch die object-position Werte berechnet.

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>

Exkurs

Es scheint, dass object-position kann mehr als zwei Werte haben, und wenn, müssen Sie einstellen (oder fügen), welcher Parameter die linke Position zurückkehrt Wert

+0

Manuelle "Komprimierung" macht den Code weniger lesbar; Lass Uglifyjs den schmutzigen Job nur für den Browser machen.In Wirklichkeit komprimiert uglifyjs den Initialcode mehr als den manuell komprimierten. (146 Bytes vs 179 Bytes) –

+0

@ bfred.it Ich stimme dir zu ... "unkomprimiert" es ein wenig :) – LGSon

+0

Danke, ich hoffte, es gibt eine API, die vor mir verborgen war. Aber die Antwort ist klar, dass es (noch?) Nicht existiert. Da Ihre Antwort die Aufgabe erfüllt, ist sie korrekt und ich akzeptierte sie. – Chris

1

Es gibt eine NPM-Paket namens intrinsic-scale das für Sie, dass berechnen, aber es unterstützt nicht das Äquivalent von object-position: https://www.npmjs.com/package/intrinsic-scale

Dies ist der gesamte Code:

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

Und die Nutzung wäre:

getObjectFitSize(true, img.width, img.height, img.naturalWidth, img.naturalHeight); 
Verwandte Themen