Fit image into a container, even when src is changed - javascript

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.

Related

Wrap content around Element on right, then Responsively above when exceeding min-width

I am trying to wrap text around an image that is positioned on the right and have the image shifted below the text when the screen becomes too small.
With these additional requirements:
The Text component has a minimum width for it's content next to the column (say 300px), which when exceeded pushes the image below the text.
The image component's size is unknown.
Images will be rendered at their native size, which may determine whether it is rendered to the right of the text or below it.
The same rules must apply when printing
Example
What have I tried?
https://codepen.io/CrocoDillon/pen/kmGCw (flawed as the image size is not pre-determined)
My current solution is a combination of various approaches. It's dirty/hacky as it uses JS to achieve part of it's goals which end up failing the print requirement.
It works as follows:
In html, render the IMAGE after the TEXT and floating the IMAGE to the right so that image is on right with text wrapped around it.
In JS, on window resize, if windowWidth - imageWidth > 300px (our min content width), update the style of the container to use flex-direction column-reverse so that the image appears below the text.
It fails the Print Requirement as the min-width check happens on window resize based on widths within window. Ideally it should now be based on the widths within the paper size/layout.
It is as follows:
HTML:
<div class="article-template-1">
<div class="article-content" ng-style="articleContentResponsiveStyle">
<div class="main-image-holder">
<div ng-repeat="imageLink in images">
<img ng-attr-src="{{imageLink.Location}}"
ng-attr-title="{{imageLink.Description}}" />
</div>
</div>
<span model="Article.Content" bind-html-compile>{{Article.Content}}</span>
</div>
</div>
CSS:
#newsArticle .article-content-holder .article-template-1 .article-content .main-image-holder {
float: right;
display: flex;
width: fit-content;
flex-direction: column;
}
#newsArticle .article-content-holder .article-template-1 .article-content .main-image-holder img {
max-width: 100%;
width: fit-content;
}
Controller:
var appWindow = angular.element(this.$window);
appWindow.bind("resize", this.updateArticleResponsiveStyle);
private exceedsMinContent:boolean = null;
private updateArticleResponsiveStyle = () => {
// The minimum size that inline content needs to be before images are repositioned
const minArticleWidth = 300;
let windowWidth = window.innerWidth;
let maxImageContainerWidth = windowWidth - minArticleWidth;
let imageContainerWidth = angular.element(document.getElementsByClassName('main-image-holder'))[0].getBoundingClientRect().width;
const previouslyExceedsMinContent = this.exceedsMinContent;
this.exceedsMinContent = imageContainerWidth > maxImageContainerWidth;
if (previouslyExceedsMinContent !== this.exceedsMinContent) {
this.$scope.articleContentResponsiveStyle =
this.exceedsMinContent ?
{
"display": "flex",
"flex-direction": "column-reverse"
} :
{
"display": "block"
}
this.$scope.$apply();
}
}
Yes, I find this incomplete solution hacky and would prefer a pure CSS approach if possible.

Having an image fill a container after transform(90deg)

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');
});

set element fit into container in panzoom.js

I wanted to use panzoom.js. My image size is larger than container. I needed to make it fit into the container by default view.
<div class="container">
<img id="panzoom" src="http://blog.millermedeiros.com/wp-content/uploads/2010/04/awesome_tiger.svg" width="900" height="900">
</div>
Here the jsfiddle
http://jsfiddle.net/Vipin/qam85n47/
Please help me to get it.
I have tried with "startTransform" value. But I needed it dynamically.
It should be calculated dynamically.
Image and container size might be changed
Try this:
$(function(){
//get parent width height
var w = $(".container").width();
var h = $(".container").height();
//set parent width height to panzoom element
$("#panzoom").width(w)
$("#panzoom").height(h)
$("#panzoom").panzoom();
});
http://jsfiddle.net/cyril123/vfqdnm8d/2/
You might want to approach it in this way:
<div class="container">
<img width="900" height="900" id="panzoom" src="http://blog.millermedeiros.com/wp-content/uploads/2010/04/awesome_tiger.svg" />
</div>
.container img {
width: 100% !important;
height: 100% !important;
}
Setting the image width to 100%, dynamic and accounts for changes in image size and container size
https://jsfiddle.net/qam85n47/11/

Height not resizing LayerSlider 5

Im having trouble with the latest version of LayerSlider. I have used everything from the full-width responsive demo and read through all the options but when I resize my browser, the height does not update. To make this clearer the image itself scales but the container's height stays the same. In the documentation it says that you must give the container a height.
My code below:
HTML:
<div id="LayerSlider" class="Slider">
<div class="ls-slide" data-ls="transition2d:1;timeshift:-1000;">
<img src="/Assets/Images/Layerslider/Banner1.jpg" class="ls-bg" alt="Slide background"/>
</div>
<div class="ls-slide" data-ls="transition2d:1;timeshift:-1000;">
<img src="/Assets/Images/Layerslider/Banner2.jpg" class="ls-bg" alt="Slide background"/>
</div>
</div>
jQuery
$(document).ready(function () {
$('#LayerSlider').layerSlider({
responsive: false,
layersContainer : 1178,
responsiveUnder : 1500
});
});
In the documentation is says you must use responsive: false if you want to use responsiveUnder which makes it responsive under a specified width.
Link to LayerSlider http://kreaturamedia.com/layerslider-responsive-jquery-slider-plugin/
All you need to do is put the container css inline.
<div id="LayerSlider" class="Slider" style="width:100%; height:427px;">
use jquery to change the #layerslider height when window resize.
<script type="text/javascript">
$(window).resize(function() {
var newHeight;
newHeight = $(window).width();
newHeight = newHeight / 2.25
newHeight = parseInt(newHeight);
// alert(newHeight);
$('#layerslider').css('height', newHeight);
});
</script>
I had the exact same problem. In my case, it was due to a duplicate of css styles, when we migrated the site to liferay cms (which adds all sorts of html). We restructured some of site and copied and pasted the layerslider.css into the document (so we could edit it without having to deploy the theme) - but never removed the original css file. Removing the styles is what fixed the height calculation. Apparently the javascript uses the css styles you set for height and width to calculate the image, text, and parent container sizes.
Hope this helps.
I used css break point to fix this height issue of the layer Slider. Use the layer slider's css editor.
#media only screen and (min-width:800px) and (max-width:960px) {
.ls-wp-fullwidth-container {
height: 65vh!important;
}
#media only screen and (min-width:768px) and (max-width:800px) {
.ls-wp-fullwidth-container {
height: 50vh!important;
}
}
#media only screen and (min-width:600px) and (max-width:768px) {
.ls-wp-fullwidth-container {
height: 42vh!important;
}
}
#media only screen and (min-width:480px)and (max-width:600px) {
.ls-wp-fullwidth-container {
height: 33vh!important;
}
}
-icodefy

How to use height() on a div with an image inside that's using width: 100%

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

Categories