2016-05-16 15 views
6

Quando si utilizza la nuova funzione CSS object-fit, come posso accedere alle dimensioni risultanti scelte dal browser da JavaScript?object-fit: ottieni le dimensioni risultanti

Quindi supponiamo che foo.jpg sia 100x200 pixel. La pagina del browser/viewport è larga 400 px e alta 300 px. Poi dato questo codice CSS:

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

Il browser ora mostrare l'immagine sulla parte superiore con la corretta razione aspetto estende fino in fondo sul secondo quarto da sinistra. Ciò si traduce in quelle dimensioni immagine:

  • width: 150px
  • altezza: 300px
  • sinistra: 62.5px
  • destra: 212.5px

Quindi cosa chiamata JavaScript (jQuery consentito) mi darebbe quei numeri che ho calcolato manualmente? (Nota: le informazioni CSS stessi non sono conosciuti dalla JavaScript come l'utente li potrebbe sovrascrivere e persino aggiungere cose come min-width)

di giocare con il codice che ho creato un violino: https://jsfiddle.net/sydeo244/

+0

se si utilizza '$ ('img.foo'). outerWidth()' si otterrà la larghezza calcolata totale degli elemen t. Non chiaro cosa stai chiedendo –

+0

No, 'outerWidth()' non funziona in questo caso poiché determinerà la larghezza dell'immagine "piena" - quindi restituire '400' a causa della larghezza': 100% 'e non' 150 'come desiderato. – Chris

+0

Non c'è una proprietà speciale che ti dia quel valore, devi usare la dimensione generata dell'elemento 'img' e quindi usare le proprietà' NaturalWidth'/'NaturalHeight' per ottenere le sue proporzioni e quindi calcolare il suo rendering dimensione (praticamente lo stesso che hai fatto manualmente). – LGSon

risposta

2

Grazie a @bfred non ho avuto bisogno di fare il metodo iniziale.

Ecco una versione estesa (e riscritta) della sua, che calcola anche i valori 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>

Nota a margine

Sembra che object-position può avere più di 2 valori, e quando, è necessario regolare (o aggiungere) quale parametro restituisce la posizione di sinistra valore

+0

La "compressione" manuale rende il codice meno leggibile; lascia che uglifyjs faccia il lavoro sporco solo per il browser.In realtà, uglifyjs comprime il codice iniziale più di quello compresso manualmente. (146 byte vs 179 byte) –

+0

@ bfred.it D'accordo con te su questo ... "non compresso" un po ':) – LGSon

+0

Grazie, spero che ci sia un'API che è stata nascosta da me. Ma i ricordi è chiaro che non esiste (ancora?). Dato che la tua risposta sta svolgendo il compito, è corretta e quindi l'ho accettata. – Chris

1

C'è un pacchetto npm chiamato intrinsic-scale che calcola che per voi, ma non supporta l'equivalente di object-position: https://www.npmjs.com/package/intrinsic-scale

Questo è il codice intero:

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

E l'utilizzo potrebbe essere:

getObjectFitSize(true, img.width, img.height, img.naturalWidth, img.naturalHeight); 
Problemi correlati