Reputation: 2267
I've been trying to scale images to fit a parent container. Here's my code:
Markup
<ul class="slides">
<li class="scale"><img src="<?php echo $attachments->src('full'); ?>" /></li>
<li class="scale"><img src="<?php echo $attachments->src('full'); ?>" /></li>
<li class="scale"><img src="<?php echo $attachments->src('full'); ?>" /></li>
<li class="scale"><img src="<?php echo $attachments->src('full'); ?>" /></li>
<li class="scale"><img src="<?php echo $attachments->src('full'); ?>" /></li>
</ul>
CSS
.fullWidth {
width:100%;
height:auto;
}
.fullHeight {
width:auto;
height:100%;
}
JS
$('.scale img').each(function(){
var img = $(this);
if (img.height() < img.width()){
img.addClass('fullWidth');
} else {
img.addClass('fullHeight');
}
});
What's weird is that although some images are portrait and some are landscape, the JS gives all the images the fullHeight
class. I want the images to scale and resize as it's parent does, as the parents use percentage dimensions. I've tried many plugins but none seem to work for me. Anyone got an idea?
Upvotes: 2
Views: 8294
Reputation: 3868
For a pure JQuery solution - set the image to be 100% width and height and scale its wrapper through JQuery:
HTML
<img class="fullSize" src="">
CSS
.fullSize{
width:100%;
height:100%;
}
JQuery
$(document).ready(function(){
function scaleContainer(){
//check height based on 100% window width
var expectedHeight = ($(window).width() * flashHeight) / divWidth;
if(expectedHeight <= $(window).height()){
//height is within the window - we can set width to 100%
$('.divWrapper').css('width', $(window).width()+'px');
$('.divWrapper').css('height', expectedHeight+'px');
}else{
//height doesn't fit - set Height to 100% and scale width
var scaledWidth = (divWidth*$(window).height())/flashHeight;
$('.divWrapper').css('width', scaledWidth+'px');
$('.divWrapper').css('height', $(window).height()+'px');
}
}
scaleContainer();
$(window).resize(function() {
scaleContainer();
});//window resize
});
Upvotes: 0
Reputation: 707158
Unless you are waiting for all the images to finish loading, then .height()
and .width()
will not return proper values as those values are only valid when the image has loaded. If they both return zero or undefined, then you will get the fullHeight class on all of them.
The solution here will be to use onload handlers and set the class when the image is loaded. Because images in the markup may load before your JS runs (particularly if they are in the browser cache), you will either have to check if the image is loaded and use it's height and width if loaded or, if not loaded yet, you will need to set an onload handler. Or, you can assign an onload handler in the markup with onload so that you're sure the load handler is installed before it loads.
Here's one way that checks to see if the image is loaded and adapts based on that:
$('.scale img').each(function(){
function setClass() {
var img = $(this);
if (img.height() < img.width()){
img.addClass('fullWidth');
} else {
img.addClass('fullHeight');
}
}
// if the image is loaded, then we can set the class now
if (this.complete) {
setClass.call(this);
} else {
// otherwise, must set class in load handler when it is loaded
this.onload = setClass;
}
});
If you can modify the markup, then you can do this which has the advantage of it's always set immediately as soon as the image loads:
Markup:
<ul class="slides">
<li class="scale"><img onload="scaleDynamic()" src="<?php echo $attachments->src('full'); ?>" /></li>
<li class="scale"><img onload="scaleDynamic()" src="<?php echo $attachments->src('full'); ?>" /></li>
<li class="scale"><img onload="scaleDynamic()" src="<?php echo $attachments->src('full'); ?>" /></li>
<li class="scale"><img onload="scaleDynamic()" src="<?php echo $attachments->src('full'); ?>" /></li>
<li class="scale"><img onload="scaleDynamic()" src="<?php echo $attachments->src('full'); ?>" /></li>
</ul>
Code:
// this must be a global function
function scaleDynamic() {
var img = $(this);
if (img.height() < img.width()){
img.addClass('fullWidth');
} else {
img.addClass('fullHeight');
}
}
FYI, if any of these images might be visible as they load, then you may want to set their default style to be visibility: hidden
and when they finish loading, set the style to visibility: visible
when you've set the scaling class and the image is loaded.
Upvotes: 1