I used js to set image width and height according to window size. But in some cases when the browser is very wide, the image's hight exceeds all its father element's height. As a result, the bottom part of the image is not shown. How can I solve this?
I used bootstrap and swiper in this project and the image I want to change is inside my swiper division. I set and all the image's father elements' height to 100%. Here is my js code to change is image dymanically. The image size is 2560*1440.
if(winWidth/winHeight < 2560/1440) {
imgHeight = winHeight;
imgWidth = winHeight/1440 * 2560;
}else {
imgWidth = winWidth;
imgHeight = winWidth/2560 * 1440;
}
attr = "width:" + imgWidth + 'px;height:' + imgHeight + 'px;margin-left: -' + imgWidth/2 + 'px;margin-top:-' + imgHeight/2 + 'px';
$('.main .swiper-slide > img').attr('style',attr);
PS:
Sorry I didn't make it clear. The following methods you provided scale the image down in vertical view and so leaves much blank in the page. Actually I want my image's height to occupy the whole window's height, no matter in vertical window or horizontal window. And if the window is wide enough, image's width equals the window's width, otherwise cut the image in width and make it equals the window's width too.
#patstuart is correct, this is much better handled directly through CSS. It's pretty amazing how many styling issues (go figure) can be solved without writing a single line of JavaScript. So to answer your second question, let's figure out how it can be done with CSS. Without seeing a fiddle or your actual page / image, I'll just shoot from the hip here. If I understand correctly, you want the full image to display at its correct ratio no matter what the width / height of the screen is. If that's the case, here's a nice little trick:
.main .swiper-slide {
width: 100%;
height: 0;
/* Padding bottom should be the height's ratio to the width.
Which in this case, would be 56.25% */
padding-bottom: 56.25%;
}
.main .swiper-slide > img {
width: 100%;
}
That is how aspect ratio can be handled with CSS. Let me know if that resolves your issue or if you have any other questions. CSS was made for styling so always look for a solution there first.
Related
I have an iframe that I want to maintain the aspect ratio at 16:9 (height/width) right now there is an box below the iframe that I don't want the iframe to ever overlap. So I can't use the padding bottom trick because it causes the video to overlap the box. How can I get the maximum width and height that the iframe can attain in the remaining space?
So for example let's say I have a window that is 1200px by 600px, 50px is used for a box. I want the iframe to take the maximum width and height on the remaining 1200px by 550px and still keep its aspect ratio and not ever go below the box at the bottom of the page. How can I do that using jquery? Also as the window resizes the iframe should keep its aspect ratio
I'm asking for the formula that embedded videos use to maintain their aspect ratio in an iframe. When I embed an iframe that has a video in it the video always maintains its aspect ratio by adding black boxes around it.
Here's the HTML:
<div class="iframe-container">
<iframe></iframe>
</div>
<div class="box"></div>
This is pretty straightforward and can be done with CSS, if you know the expected aspect ratio. For video embeds at 16:9 (56.5%), it's done like this.
You can add max-height and max-width properties to the container just as you would any other element. The height is 0 and the padding is simply set according to the aspect ratio you want. The iframe is set to fill the container width and height so it will conform to the aspect ratio based on the padding.
.iframe-container {
position: relative;
padding-bottom: 56.5%;
height: 0;
}
.iframe-container iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
Update: You can do this much better with vw units.
This will work if your iframe is intended to be the full width of the browser. Otherwise you can do some calculations on it. But, for a full width iframe that you want to preserve aspect ratio on, it goes as follows (for 16:9 aspect ratio):
iframe {
width: 100vw;
height: 56.5vw;
}
Maintaining an aspect ratio is pretty straightforward with some conditional math, over time.
Generally, we have a container, a thing contained, and a known ratio (16/9). The height or the width can be determined by trapping the thing in the container (checking for out of bounds) and computing the other value from the ratio.
Update : once you have the new values, check for out of bounds. In this case, a min height and a max width.
A bit like so:
// if the iframe height (container width / ratio) is greater than the container height
if ( (cW / RATIO) > cH){
h = cH; // set the height equal to the container
w = cH * RATIO; // set the width equal to the container height * ratio
} else {
w = cW; // set the width equal to the container
h = cW / RATIO; // set the height equal to the container width / ratio
}
// Ok so, now that the iframe is scaled up, check for out of bounds
if ( iH < MIN_HEIGHT ){
iH = MIN_HEIGHT; // set the height to the const
iW = iH * RATIO; // use the same basic formula, but use the new value
}
if (iW > MAX_WIDTH){
iW = MAX_WIDTH; // set the width to the const
iH = iW / RATIO; // same formula, new value
}
- Working fiddle with some discussion.
- Updated fiddle with some out of bounds checks.
You can, obviously, work some extra math into the computation to make space for a control bar, or whatever. This is just the basic principle, in a very simple state. I almost always have some additional checks against max width, or do some positioning or whatever. But this should be a good start.
Cheers -
I am trying to make a picture take up 70% of the user's screen. However, if the screen is made smaller when the page is loaded or if the person has inspect element open, the picture becomes small and stretched. I believe the best solution would be to find the maximum height of the browser window and make the image that size. However, I am not sure how to do that?
Here is my current code for image sizing:
var topoffset = window.innerHeight * 0.77;
var profilestart = topoffset - $(".prof-header").height();
$('.splashPic').css("height", topoffset);
$('.splashPlaceholder').css("top", profilestart);
I also want to make it so that if someone is using a huge monitor (i.e. large Mac), the image size maxes out at that point? Any suggestions would be very helpful!
Edit: I don't want to make the image resize dynamically. Only load once.
Use window.screen.availHeight instead of window.innerHeight
or screen.height
var x = screen.height*0.7;
EDIT: Here's more code to show that it works for what you asked. Gets the height upon load and doesn't resize.
<img id="img2" src="http://lorempixel.com/320/240/food" />
<script>
$(document).ready(function () {
var x = screen.height*0.7;
$('#img2').css("height",x);
}
</script>
It sounds like what you want to do is something like this:
img{
display:block;
width:70%;
min-width:320px;
max-width:1200px;
}
If you want the image to take up 70% of the viewport height (and obviously retain its ratio) you could use the new css unit vh (viewport height) like this:
img
{
height: 70vh;
}
FIDDLE
I'm designing a web page that has a photo for a background image of the main page.
The image must cover as much of the available window size as possible, whilst maintaining the correct aspect ratio.
To that end, I have a "container" div with the following CSS:
div.background {
background-image: url('/Content/Images/Home/main-bg.png');
background-repeat:no-repeat;
background-size:contain;
background-position:center;
float:left;
width:100%;
}
which is working perfectly.
However, I now need to position additional dom elements at specific places on the image, which are also scaled to the same as background image.
I initially thought that using JQuery and reading the "background-image-x","background-image-y", "background-image-x", "background-position-x", and "background-position-y" CSS properties might give me the information I need to position the additional elements.
However, these are not returning the needed information (for example, image-x and image-y both return "50%").
Is there some nice and simple(ish) way to achieve what I need... or am I going to have to resort to using Javascript and math to manually set the position and size of the background image (thus giving me the answers I need)?
I hate math. Please don't make me use it :)
You could work this out with some quite simple comparative ratios, of the image width vs image height compared to container width vs container height. To work out whether the image will be scaled horizontally or vertically.
img_ratio = img_width / img_height;
container_ratio = $(elm).width() / $(elm).height();
Following that you can work out the offset quite simply as you can work out by what percentage the image has been scaled. And apply that to the opposite mesasurement, and compare it to the container.
if(container_ratio > img_ratio){
//centered x height 100%
var scale_percent = $(elm).height() / img_height;
var scaled_width = img_width * scale_percent;
var x_offset = ($(elm).width() - scaled_width) / 2;
offset = [x_offset, 0];
}else{
//centered y width 100%
var scale_percent = $(elm).width() / img_width;
var scaled_height = img_height * scale_percent;
var y_offset = ($(elm).height() - scaled_height) / 2;
offset = [0, y_offset];
}
I've wrapped this up in an example fiddle at: http://jsfiddle.net/y2LE4/
I hope to help.
Try with:
$(document).ready(function(){
var something = background.offset();
}
or
$(document).ready(function(){
var something = $('.background').outerWidth(true);
}
Or just the width feature: http://api.jquery.com/width/
I'm using some script I found on Git that generates a snow effect. Somewhere in the code I have to set the width and the height of the canvas in which the snow is generated. I'm setting the canvas to the window full width / height :
canvas.width = $(window).width();
canvas.height = $(window).height();
But when rendered in the browser there are on both height and width some extra pixels adding scrollbars to the window. You can see the behavior here : Canvas ; I'm not quite sure why the width / height is calculated wrong or if there's something else interfering with those calculations that it makes it bigger than the actual window width / height. Maybe someone has a different view of the behavior or encountered it before ?
The canvas element is displayed inline by default, you can read here about similar problem.
The solution is quite simple :) Add following css code to the canvas element:
display: block;
and scrollbars should disappear.
old answer:
$(window).width() works properly but i don't know why $(window).height() returns too large value. It cause also showing vertical scrollbar because earlier computed width don't include the size of horizontal scrollbar.
I'm trying to write my own lightbox script but I'm stuck on a problem.
The wrapper div centering is done through position: absolute and top / left positioned by calculating...
top:
_center_vertical = function() {
return (($(window).height() - wrapper.height()) / 2) - (options.margin + options.border) + $(window).scrollTop()
}
left:
_center_horizontal = function() {
return (($(window).width() - wrapper.width()) / 2) - (options.margin + options.border) + $(window).scrollLeft()
}
The wrapper div is centered on .load() and on $(window).resize() / $(window).scroll().
When the image is loaded and appended to wrapper, top and left is calculated using the functions above, horizontal centering is correct, but vertical centering is not. It is off by around 10px or more.
When the browser window is resized or scrolled, it calls the function which animates the centering which uses the same function to calculate the top and left. The window resize / scroll does center the image properly.
I have tried using jQuery deferred.then() to have it calculate the top / left after the image is appended, but it didn't change anything.
Example: http://jsfiddle.net/vfMNQ/
I initially thought that the difference in top position changed when I played around with things like wrapper padding (aka my border), however, I found that I was wrong.
I added some console.log('image load height: ' + ((($(window).height() - wrapper.height()) / 2) - (options.margin + options.border)) + 'px') to .load() and .scroll() and found that the difference was oddly 21px no matter what. The default border is 10px, margin is 30... so where did the 21 come from?
I'd hate to use + 21 as a hack, but seems like nobody can figure it out.
Your problem appears to be in the loading div:
.lbe-loading {
background: #578DB2 url(/public/images/loading.gif) no-repeat center center;
width: 32px;
height: 32px;
padding: 5px;
}
height:
32 + padding: (5 * 2) = 42
42 / 2 = 21px
Looks like you've appended the image with the loading div still appended to the wrapper.
wrapper.append(loading);
...
$(function() {
var img = $(new Image());
img.load(function() {
wrapper.append(this) // .lbe-loading still appended here
.css({ // Position wrapper.
...
});
loading.remove(); // Too late.
If I remove .append(loading), it centers fine.
Put .lbe-loading on a different div so it's not being added to the wrapper's height.
Best guess:
You are trying to calculate the height of the wrapper before actually putting in the image.
i.e. you are append(this) and then immediately trying to calculate the height before giving the browser a chance to display and load the image.
When I put in debugging code wrapper.height() changed by 40 pixels after resizing the display. 40 pixels is exactly the border + margin. (And when I changed those, the difference changed too.)
Its a delay in wrapper getting the height and width of the image. The jQuery for centering is executing before Browser has preformed its reflow and given 'wrapper' the height and width of the image.
I forked your fiddle and fixed it here: http://jsfiddle.net/3th5k/
by setting wrapper's height and width with javascript before centering. This way your centering calculation draws from the right data source, the javascript image object rather than the dom.
Also please note that the css statement with 'opacity: 0' has been replaced with .hide(); I did this because opacity and ie are not friends and it would most likely cause a problems down the line.
Cheers!