I have a mobile first slider with 3 types of images: tall, horizontally long and square. I want the horizontally long image determine the size of slider and then scale and center other ones to fit it's size. Using width:100%; height:auto; in my CSS code so images will be loaded with same width(100%) and different heights. Then using JS I want to get height of the image which has max width/height ratio and use it as the height of all images. And in the end using width:auto; height:100%; for images so all of them will fit the height. Here is the code I used to achieve this:
every slide has the following HTML:
<div class="img">
<img src="" alt="">
</div>
CSS code:
.img{
position: relative;
vertical-align: middle;
}
.img img{
width:100%;
height:auto;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
}
JS code:
$(".img img").width = "100%";
$(".img img").height = "auto";;
var img_h , Imgs_heights=[] , ratio=[];
slider.item.find(".img img").each(function(){
Imgs_heights.push($(this).height());
ratio.push($(this).width()/(($(this).height())));
});
img_h = Math.max.apply(Math,ratio);
var i = r.indexOf(img_h );
$(".img").height(Imgs_heights[i]);
$(".img img").css("height", "100%");
$(".img img").css("width", "auto");
Everything works just fine but I have problem when I resize the window. In resizing the height of images does not change and keeps the height calculated before. And I need to refresh page to see the result I want. How can I get the height to change? I added the two first lines in JS to force it take width:100%; height:auto; again in resized window but it does not work.
I will appreciate any help.
If I'm understanding you correctly, can you simply use the Javascript window.resize event to recalculate the image sizes?
From Mozilla https://developer.mozilla.org/en-US/docs/Web/Events/resize
The resize event fires when the document view (window) has been
resized.
Your code might become something like:
function resizeImages(){
$(".img img").width = "100%";
$(".img img").height = "auto";
var img_h , Imgs_heights=[] , ratio=[];
slider.item.find(".img img").each(function(){
Imgs_heights.push($(this).height());
ratio.push($(this).width()/(($(this).height())));
});
img_h = Math.max.apply(Math,ratio);
var i = r.indexOf(img_h );
$(".img").height(Imgs_heights[i]);
$(".img img").css("height", "100%");
$(".img img").css("width", "auto");
}
window.onload = function(){
resizeImages();
};
window.onresize = function(){
resizeImages();
};
Related
On mouseover I want to move the "imgbox" to a specific absolute position (which might move it on top of the "i" image).
The second image ("newimg") loads, so that part works (including hiding it again in "onmouseout") but it's displayed below everything (like in the HTML code). It seems like setting imgbox.style.left and imgbox.style.top doesn't do anything. If I set "margin" instead, the image is displayed 200px to the right and 200px down from where it originally was (but still below everything else).
What did I miss? How do I move the "imgbox" at runtime with regular Javascript (no JQuery please!)?
function onHoverIn(url) {
var imgbox = document.getElementById("imgbox");
imgbox.style.visibility='visible';
var newimg = document.createElement("img");
newimg.src = url;
var oldimg = document.getElementById("i");
/*if(oldimg.addEventListener){ //Removed so the snippet'll run
oldimg.addEventListener('mouseout',onHoverOut,false);
} else {
oldimg.attachEvent('onmouseout',onHoverOut);
}*/
imgbox.innerHTML='';
imgbox.appendChild(newimg);
imgbox.style.left = '200px';
imgbox.style.top = '200px';
//imgbox.style.marginLeft = '200px';
//imgbox.style.marginTop = '200px';
}
#imgbox {
position : absolute;
border: 1px solid #999;
background : #FFFFFF;
filter: Alpha(Opacity=100);
visibility : hidden;
z-index : 50;
overflow : hidden;
}
<img id="i" src="https://i.pinimg.com/originals/53/02/a4/5302a4c318139bf5753c433b1f4c6aa8.jpg" alt="DP" onmouseover="onHoverIn('https://i.pinimg.com/originals/b2/1b/07/b21b0738ea390fc56a4d3efe76ab88de.jpg')">
<p>Long Teeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeext<br><br><br><br><br>END TEEEEEEEEEEEXT</p>
<div id="imgbox"></div>
Sorry, the images are pretty big, so not sure how well it'll work. I tested the code with Firefox 85.0, Chrome 88, IE and Edge by simply double-clicking the .html file and the positioning doesn't work properly in any of them.
This was quite a bit harder than I thought it would be, made some changes to your code. Hope this still works for you.
NOTE: I implemented an onHoverOut locally and noticed that when I moved my mouse around on the image it would flicker. This happens because the new image is loaded and once moving again the old image registers a onHoverOut (because you hover on top of the new image) which would then remove the new image, at which point the old image registers the onmouseover again and adds the new image. This would keep looping for as long a you move the mouse around.
function onHoverIn(url) {
var imgbox = document.getElementById("imgbox");
imgbox.style.visibility='visible';
var newimg = document.createElement("img");
newimg.src = url;
var oldimg = document.getElementById("i");
if(oldimg.addEventListener){
oldimg.addEventListener('mouseout',onHoverOut,false);
} else {
oldimg.attachEvent('onmouseout',onHoverOut);
}
//imgbox.innerHTML='';
imgbox.appendChild(newimg);
}
function onHoverOut() {
console.log('onHoverOut: not implemented');
}
.article{
width:640px;
padding:0 16px;
}
.image-box{
position:relative;
width:100%;
height:0;
/* 16:9 */
padding-top:56.25%;
overflow:hidden;
}
.image-box img{
position:absolute;
top:0;
width:100%;
}
<div class="article">
<p>content before..</p>
<div id="imgbox" class="image-box">
<img id="i" src="https://i.pinimg.com/originals/53/02/a4/5302a4c318139bf5753c433b1f4c6aa8.jpg" alt="DP" onmouseover="onHoverIn('https://i.pinimg.com/originals/b2/1b/07/b21b0738ea390fc56a4d3efe76ab88de.jpg')">
</div>
<p>content after..</p>
</div>
I would like to have an image rotate and fill the container after it's been loaded. The issue I'm having is the height is automatically set when loaded and then not resetting after rotation. Here is a JSFiddle of the issue:
$('.load').on("click", function () {
var image = $('.image');
image.attr("src", "https://s-media-cache-ak0.pinimg.com/736x/f5/a0/62/f5a0626a80fe6026c0ac65cdc2d8ede2.jpg");
image.addClass('rotate-image');
});
.image {
max-width: 100%;
max-height: 100%;
}
.rotate-image {
transform: rotate(90deg);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="img-container" style="background:black; height:100px; width: 200px; text-align:center">
<img class="image" src="" />
</div>
<br />
<button class="load">Load</button>
This requires the max-width and max-height styles to be removed, though.
To fit the image, it has to be made larger so that it width (height, when rotated) becomes as big as the container's height. However, it's rotated only visually and the browser doesn't care about that because transform doesn't change the flow of the website. For it, there is an "unrotated" picture whose height is now bigger than its container. Visually rotating the image doesn't change anything. For that purpose, the image needs to be pulled up with a number of pixels equal to how much its bigger than the parent. Those pixels are divided by two because the image overflows at the bottom only.
Play with the fiddle to see what I mean.
$('.load').on("click", function() {
var image = $('.image');
image.attr("src", "https://s-media-cache-ak0.pinimg.com/736x/f5/a0/62/f5a0626a80fe6026c0ac65cdc2d8ede2.jpg");
image.addClass('rotate-image');
var parentHeight = image.parent().height();
image.css("width", parentHeight + "px");
image.css("position", "relative");
image.css("bottom", ((image.height() - parentHeight) / 2) + "px");
});
.rotate-image {
transform: rotate(90deg);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="img-container" style="background:black; height:100px; width: 200px; text-align:center">
<img class="image" src="" />
</div>
<br />
<button class="load">Load</button>
Edit: Beware, if you load the image from an external source by setting its src and immediately rotate it, image.height() might return 0 and the image might be displaced. Then, if you click again, its height is now correct and it gets placed right.
I'm not absolutely sure, but I think that's because when you load the image, the browser needs to download it first, meaning that you don't yet know what its dimensions are.
To see that in action, paste some image URLs from Google in the fiddle I provided.
You need to do this by javascript or jquery. Your goal is:
.Rotated_Img ...
width = 100 % of parent height
height = 100 % of parent width
And i do not think css has any think for this, until the parent width and height have related to view port vw and vh.
jquery:
$('.Rotated_Img').each(function(){
$(this).css('width', $(this).parent().height() + 'px');
$(this).css('height', $(this).parent().width() + 'px');
});
I'm sure there are other post that address this in various ways.
I've been struggling with this a bit, trying to do CSS only approach with no luck. Playing around with css width and height, doing a mix of 100% and auto on the image got me nowhere.
Given html:
<div class="container">
<img src="http://image" />
</div>
And css:
.container { width: 500px; height: 400px; }
How to fit images of various sizes into the container while preserving aspect ratio and obeying constraints of the container?
I believe you are far over-thinking this.
Try adding the following CSS, and removing the javascript:
.container img {
max-width: 100%;
max-height: 100%;
}
Here's a demo (click the images to dynamically load a different size)
I ended up with javascript solution - I know, not ideal but it's the best I could come up with that does what I need it to. The page where I'm using this relies on javascript to perform other bits of functionality so that's not a problem in my scenario. I'm also loading images into a Bootstrap grid layout column, like so:
<div class="row">
<div class="col-md-6">
<div class="main-image">
<img src="http://initialimage" />
</div>
</div>
<div class="col-md-6">
Some content here ...
</div>
</div>
The width of the container in this case is controlled by bootstrap layout css so I only need to set the height of the container:
.main-image { height: 400px; }
I tried with using just
.main-image { max-height: 400px; }
So that the container would adjust to horizontally stretched images but then jQuery gets the container height wrong.
Anyway, here's the javascript I'm using:
var imageLoaded = function () {
var container = $(this).parent();
var maxWidth = container.width();
var maxHeight = container.height();
var width = $(this).width();
var height = $(this).height();
var containerRatio = maxWidth / maxHeight;
var ratio = width / height;
if (ratio > containerRatio) {
$(this).attr('width', '100%;');
$(this).attr('height', 'auto');
}
else {
$(this).attr('height', '100%;');
$(this).attr('width', 'auto');
}
};
$(document).ready(function () {
$('.main-image img').bind('load', imageLoaded);
imageLoaded.call($('.main-image img'));
});
You may wonder why the manual invocation of imageLoaded function - it's because in IE, the event doesn't fire for the initially loaded image. Invoking it manually corrects that.
You can then change the image source:
$('.main-image img').attr('src', 'http://otherimage');
And the image will adjust to fit the container by either using up full height for vertical images or full width for horizontal images.
Any better way to do this or comments welcome.
I am trying to center this brand logo vertically and horizontally on the whole page with JQuery. It does work on browser resize but not initially. Notice this code resizes the image to fit the page. I tried $(window) and $(document) JS is:
$(function() {
var resizeToFit = function(){
var $this = $(document);
var imgw = $("#overlay-logo img").width();
var pw = $this.width();
var $overlaylogo = $("#overlay-logo img");
$overlaylogo.css("width", pw - 100);
var left = (pw / 2) - (imgw / 2);
$overlaylogo.css('margin-left',left);
}
$(window).resize(function(){
resizeToFit();
});
resizeToFit();
});
CSS:
#overlay-logo{
position:absolute;
top:50%;
z-index: 999999;
}
HTML:
<div id="overlay-logo">
<img src="img/overlay.png" alt="overlay" />
</div>
you should be able to do this with just straight css.
#overlay-logo{
height:99%;
width:99%;
margin:auto;
position:absolute;
top:0;
right:0;
left:0;
bottom:0;
}
here's a fiddle: http://jsfiddle.net/GheZd/
EDIT
Just make your height and width 99% then. You can put apply this style directly to the image...you don't necessarily need the div.
so I have
div {
width: 20%;
}
img {
width: 100%;
}
<div>
<img />
</div>
So the image scales appropriately, depending on the width of the div. I want to find the height of the image using jQuery.
var imgHeight = $(img).height();
console.log(imgHeight);
However, it's coming back as 0 (the height of the div). How do I get the rendered height of the image?
Thanks!
As loganfsmyth has commented, the you need to wait for the image to finish loading.
Are you putting the code in document.ready ?
$(document).ready(function() {
var imgHeight = $(img).height();
console.log(imgHeight);
});