Javascript image panel with images the same size - javascript

What is the best way to display a panel of different sized images as all being the same size. Is there a simple Javascript framework that can handle the resizing and possibly some cropping.
For example if you look at Pinterest you will see that all the images have variable sizes (we can use jQuery masonry for this). But then when you look at this page, http://pinterest.com/pin/97249673174024268/ all the images are the same size.
Firstly is my question sensible and secondly is there a way we can achieve this with a Javascript library.

If you want to do this entirely in JavaScript, it's simple enough that you don't need a library. If you have jQuery, it makes it even easier.
Place the image inside a <div> with the width and height set to your desired size, 'overflow' set to 'hidden', and 'position' is either 'absolute' or 'relative'.
Get the size of the image:
var imageWidth = $(image).width(),
imageHeight = $(image).height();
(If it was loaded into a JavaScript Image object, you can also just get it from image.width and image.height)
Do a bit of math figure out how much to shrink or enlarge it:
var widthScale = divWidth/imageWidth,
heightScale = divHeight/imageHeight,
scale = Math.max(widthScale, heightScale),
newWidth = Math.round(imageWidth*scale),
newHeight = Math.round(imageHeight*scale);
Essentially,this figures out how much it would need scale the image to make the width fit and to make the height fit, then picks the larger of the two so the image fits on one side and overflows on the other.
Style the image to fit the new size and center it inside the div:
$(image).css({
width: newWidth+'px',
height: newHeight+'px',
position: 'absolute',
left: '50%',
top: '50%',
margin-left: 0-Math.round(newWidth/2)+'px',
margin-top: 0-Math.round(newHeight/2)+'px'
});
That should do it!

This plugin here can handle varying image sizes and arrange them like you want.

Related

How do I double the size of an image on a web page?

I have an image, say 320 x 240 pixels in size, which I want to display doubled in size (i.e. 640 x 480 pixels) on a web page. In the past, I have done this by setting width=640 on the img tag.
However, I have just spotted the following in the HTML specification:
The dimension attributes are not intended to be used to stretch the image.
In that case, how do I double the size of an image on a web page without going against what the spec intends?
You can use CSS instead. The two methods that jump to mind are using the width or scale transformation.
E.g. img { width: 640px; }. This will keep the proper aspect ratio without specifying the height.
img {
width: 640px;
}
<img src="http://www.placehold.it/320x240">
E.g. img { transform: scale(2) }
img {
transform-origin: top left;
transform: scale(2);
}
<img src="http://www.placehold.it/320x240">
You can set the dimension of the parent image container
.imageContainer {
width: 640px;
height: 480px;
}
img {
width: 100%;
height: 100%
}
<div class="imageContainer">
<img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQqdnZQDnZOOyBGXXB23WS87IAxZ85drC-ylgrqWCqYk2aEh3Vo">
</div>
Via CSS, ideally in a style sheet, but in the style attribute if necessary.
For instance, here's your 32x32 gravatar stretched to 128x128:
.stretch-128 {
width: 128px;
height: 128px;
}
<img src="https://www.gravatar.com/avatar/6b938dc4205cd0cea4e4e68451c42a21?s=32&d=identicon&r=PG" class="stretch-128">
Naturally, any time you stretch an image like that, the quality is likely to suffer.
First I created a div with a class named divWrapper with a specific size. We then create a class for our image with a width of 100%(which spans across the divWapper), and added a height of auto(To automatically keep the height in proper proportion). You can adjust the size of the image according to the divWapper class.
.divWrapper{
width:640px;
height:480px;
float:left;
}
//Now set you image class to
.imageclass{
width:100%
height:auto;
float:left;
}
<div class="divWrapper">
<image class="imageclass" src="https://upload.wikimedia.org/wikipedia/commons/2/2d/Picea_glauca_taiga.jpg">
<div>
This will keep the image in proportion no matter what size the wrapper container is.
A Helpful Note:
You must have a high quality image from the start I suggest using vector images. I prefer to Use PNG or SVG. It has better quality than jpeg and others.
Here are a couple of link that describes a little about image extensions.
https://blog.online-convert.com/best-image-file-extensions/
https://www.sitepoint.com/gif-png-jpg-which-one-to-use/
There are at least 4 ways to do this.
1. directly set width attribute of img
principle: modify the width of the image.
set width: 640px; display: block for the img tag.
2. wrap img with a div
principle: inherit the width from parent node.
div width: 640px
img display: block; width: 100%
3. set the image as background of a div
principle: the image is no longer a img tag, but the background of a node.
div background-image: url(), use the image as background image.
div background-size: {2x width} {2x height}, to resize the size of the image
4. scale the image into 2x
set the transform property to scale(2), which means I want the size of it 2 times of its original size
tips: also, we need to set the property transform-origin into top left, in order that it can start from the position(relatively) top: 0; left: 0;
Run the snippet and have a look :)
.method-1 {
display: block;
width: 640px;
}
.method-2 {
width: 640px;
}
.method-2 img {
display: block;
width: 100%;
}
.method-3 {
width: 640px;
height: 480px;
background-image: url(http://www.placehold.it/320x240);
background-size: 640px 480px;
}
.method-4 {
transform-origin: top left;
transform: scale(2);
}
<h1>method 1: img displays as block, width 640px</h1>
<img src="http://www.placehold.it/320x240" class="method-1" />
<br/>
<h1>method 2: parent dom width 640px, img width 100%.</h1>
<div class="method-2">
<img src="http://www.placehold.it/320x240" />
</div>
<br/>
<h1>method 3: the img as div's background, use the background-size attribute to set 2x size.</h1>
<div class="method-3"></div>
<br/>
<h1>method 4: use CSS3 transform property to scale the image into 2x.</h1>
<p>tips: when we set `transform: scale(2);`, we also need to define the `transform-origin` property to `top left`, in order that the image will align from top to bottom as well as from left to right, or it will lost itself. LOL.</p>
<img src="http://www.placehold.it/320x240" class="method-4" />
Here's a list of things you want to avoid when loading an image:
FOUC - which happens when the browser does not have the image size before loading it (in which case it doesn't allocate any space for it until it's fully loaded) or telling the browser the wrong size
distortion (displaying an image at a different aspect ratio than 1:1)
pixelation (displaying an image at a significantly bigger size than its native size)
loading images with significantly bigger native size than the size in page - they slow the page down and consuming unnecessary bandwidth
There are ways to deal with each of the above.
For avoiding FOUC, there are a few methods:
have the image sizes (or ratio) saved, besides the file itself, so you can allocate the correct space in page flow, before loading the images (WP does this out of the box, for example and most themes use it to avoid FOUC)
have the image load in a container, as background image with background-size: cover, so FOUC is not possible, as the document already knows the size of the element, before the image is loaded. This technique also has the advantage of not displaying broken image anchors when an image fails to load. Also, this technique is widely used today in full screen image layouts, some of them using parallax effect. Has the disadvantage of cropping top/bottom or left/right, depending on aspect ratio difference between container and image.
load the image in a position:absolute centered container and when you have its size (and are able to calculate exact position in document flow) animate its scale from 0 to 1 while also animating its container size from "default" to proper size.
Regarding distortion, there isn't much to say, except do not do it. Any other option is better than distortion: cropping, pixelation, even FOUC. Distortion basically says: "Don't trust me with design tasks - I'm unable to tell does from donts" - which, to many, translates to: "I'm unqualified for professional frontend development. I'll mess up any website coming my way, most likely without knowing".
On pixelation. It's a tricky one: you want the page to load as fast as possible, but also want crisp images. When dealing with very large background images, a neat trick is to add a pattern over the image (stripes, dots or any other such semi-transparent patterns - an artistic touch to make pixellation a lot less noticeable).
Another good and smart technique for getting best of both worlds (speed and image quality) is to:
load a proportional thumbnail versions for every image below the fold (yes, they'll look pixelated) and display them at .65 opacity. Lazy load the full size images before they are scrolled into view. Even if the pixelated version is visible for a short while, it will be replaced by the full-size one, creating a focus-in effect, together with changing opacity to 1. If you have quality, outstanding images, you really want this effect (a) because it makes them stand out and b) because you want to load the images at proper, crisp size). The images will look "alive" and get subtle focus, leaving visitors with the impression of looking at a highly sophisticated website.
Avoid oversizing. Here src-set comes into play, combined with the thumbnail loaders described above. And, of course: lazy-loading. Always lazy load anything below the fold. It makes a big difference.
In short, that's how you correctly load images. In reality, it's a huge subject, I haven't even touched optimization, raster vs vectors, svg's or webp formats.
You can achieve this by two way as below.
<img class="xx" src="http://placehold.jp/150x150.png">
.xx {
zoom: 200%;
}
.xx {
transform: scale(2);
}
Generally I haven't found an article providing a way to scale images with client side technologies (leave it the browser's mechanism) without losing some quality.
With that being said I am afraid that If you want the best way to double your image according to HTML Standard specifications the best answer is to use a different image. A scaled up image through back-end process or through Photoshop. Now if you want adaptive image according to the user's screen since most probably this is the actual case the HTML Standard to achieve that is with the following way:
<picture>
<source srcset="http://www.placehold.it/320x240" media="(min-width: 600px)">
<source srcset="http://www.placehold.it/640x480" media="(min-width: 900px)">
<img src="http://www.placehold.it/160x120">
</picture>
Out of my experience the best way to double the size of any image for usage in websites is to actually double the image in a program like Photoshop and then upload it.
The image size, the pixel density for the retina screens, and the plethora of different screen sizes makes working with images a little more advanced than it used to be, but nothing too hard.
check the following example:
<picture>
<source
sizes="(width < 32em) contain, (width >=32em) contain 80vw calc(100vh - 10em)"
srcset="full.jpg 2048h 1024w, half.jpg 1024h, quarter.jpg 512h, eighth.jpg 256h" />
<img src="eighth.jpg" alt="rose flower!" />
</picture>
You upload a relatively big image, at least FHD, or bigger, and then with the 'sizes' and 'srcset' you configure it, which one to load depending on the screen size/type.
This way you cover any potential resolution, small or big, and you always display the best version of your image.
Ok, i admit it, there is some manual labor work to happen in every image prior the uploading, but the final result is worth it!
Now if you insist of keeping the same small image file and double it via using coding, then the best way is to add a CSS class to your image, and on that class specify your doubled dimensions, and that's it.
Here is a funny and good explanation about images srcset, sizes, and the importance of why we need to do it this way.
A fun article on srcset
You can user javascript for like this way this to change image size by it's double
Check this JsFiddle Demo
<html lang="en">
<head>
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$("button").click(function(){
var img = $("#sky");
// Create dummy image to get real size
$("<img>").attr("src", $(img).attr("src")).load(function(){
var realWidth = this.width;
var realHeight = this.height;
alert("Original width=" + realWidth + ", " + "Original height=" + realHeight);
var newWidth = realWidth * 2;
var newHeight = realHeight * 2;
$("#sky").width(newWidth);
$("#sky").width(newHeight);
alert("new Image Size" + newWidth+"x"+newHeight);
});
});
});
</script>
</head>
<body>
<img src="https://www.cluedin.net/images/providers/stackoverflow.png" id="sky" width="250" alt="Cloudy Sky" contextmenu="skymenu">
<p><button type="button">Get Original Image Size And Double it</button></p>
</body>
</html>
I like most of the previous solutions, but the issue here is that we don't actually know the current image size to double it!!
So, my solution is kinda dynamic, and it won't affect other images on your website as well.
Also, it can be enhanced to triple their sizes, and more if you wanted!
Check a Live Preview here.
Or read it below:
HTML
<img class="resize-double" src="https://placeimg.com/100/50/nature">
<img src="https://placeimg.com/200/100/nature">
JavaScript
// Select all images to be resized
const toResizeImgs = document.querySelectorAll(".resize-double");
// Loop over those images and double their size
for(let i=0; i < toResizeImgs.length; i++) {
toResizeImgs[i].style.width = toResizeImgs[i].offsetWidth * 2 + "px";
toResizeImgs[i].style.height = toResizeImgs[i].offsetHeight + "px";
}
It would select the images with the class resize-double, loop on them and change their width/height to 2x of the current one!
NOTE: BothoffsetWidth and offsetHeight return the current width/height including Margins, Paddings and Borders. If it doesn't suit you, you can use clientWidth and clientHeight, or even scrollWidth and scrollHeight based on your needs!
The most optimal way is to load the biggest image to your site and downscale it where you need through CSS.
1) Best quality for your image since upscaling distorts the image.
2) No need to load more images with different sizes
3) Downscaling does not spoil the image and it is just some lines of CSS
If you don't want to load the bigger image, the second best and fastest solution is to upscale it through CSS. Width attribute no longer works in <img>
You can do that many various ways. But whatever you do, first download your image which size you want it to mean the double size otherwise if you double the size, then it gets pixelated or looks faded.
image{ transform: scale(2); }
Try transform scale to double sized your image
Try setting the width in the image with CSS
Try with JavaScript with setAttribute("width", "size")
Well you can use css and avoid stretching.
img{ width:640px; background-size: cover; height:auto;}
This will stretch your image equally with suitable height. You can also try setting height to a specific number.
The dimension attributes are not intended to be used to stretch the image.
As you already mentioned that using width attribute doesn't intend to stretch the image. so in that case we should use transform: scale(2); which is a good idea but this may also get conflict regarding image overlapping other content, so best idea is to use 2x width of div with image scaled 2x with css property 'transform: scale(2);'
Hence: using the below style should be a good idea.
.img2x_container {
width: 640px;
height: 480px;
}
.img2x_container img {
transform: scale(2);
}
This use case is only beneficial when we know the image height and width.
You can make use of transform -> scale
img#imagId {
-ms-transform: scale(2); /* IE 9 */
-webkit-transform: scale(2); /* Safari 3-8 */
transform: scale(2);
}
I use following Java Script code to scale image according which can fit best in container. You may make few changes per your need.
function scaleImage(container, image) {
var c = document.getElementById(container);
var i = document.getElementById(image);
var newSize = scaleSize(c.clientWidth, c.clientHeight, i.width, i.height);
i.style.width = newSize.width;
i.style.height = newSize.height;
c.style.backgroundColor = "transparent";
c.style.border = "none";
var intHeight = ((100-((parseFloat(i.style.height)/87)*100))/2);
var strHeightPercentage = intHeight.toString().concat("%");
c.style.top = strHeightPercentage;}
function scaleSize(maxW, maxH, currW, currH) {
var ratio = currH / currW;
if (currW >= maxW && ratio <= 1) {
currW = maxW;
currH = currW * ratio;
}
else if (currH >= maxH) {
currH = maxH;
currW = currH / ratio;
}
return { width: currW, height: currH };
}
CSS trick, setting just one property
If you want to use CSS, there's a really good way:
img#image_id {
width: calc(2 * 320px);
height: auto; /* This can be omitted */
}
This is very useful which you can change the scale of the image by changing just one number (i.e. the factor). No worries about the image height, it will be set automatically by the browser, even if you omit setting image height to auto (because auto is the default value of width and height; see this and this). Also, you can set height instead of setting width.
It would be useful for responsive design in a way, and I think it's really tricky!
Note: It doesn't work with flex-boxes, if you set the parent's width or height. In this case, you must explicitly set width and height, or there would be another tricks for that; flex-boxes works completely different.
The most complex stuffs are hidden in the simplest!
What they mean to me by this sentence is to «take care of scalability».
And for that, there is nothing better than svg. We need to think about caching. Just avoid to embed them directly. Let the client browser do the caching by using external src.
As soon as this is well done, we can scale it at moon size, keeping it smooth...
Svg can be generated server side, but it's always better to carefully create them with (gimp). Then open the svg with a text editor.
If using images, currently, for nice rendering in different screen resolution, the best should be to use a set of them in different resolution, with srcset. Finally just like other dynamics elements, let the client browser do the choice by providing him many options. Again, with caching in mind. it will download and keep only the one it need.
If an html solution exist, we should use it before trying to alter it (by js or css).
https://css-tricks.com/responsive-images-css/
A new css property is in town: image-rendering.
https://drafts.csswg.org/css-images-3/#the-image-rendering
As usual, the most complete answer are the specs!
https://drafts.csswg.org/css-images-3

change image manually as window sizes

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.

Scale images in each row to fill it 100% with JavaScript or CSS

I'm trying to build a simple responsive gallery.
Code pen here
There only a simple CSS setting for images now:
img {
height: 150px;
float: left;
margin: 2px;
}
I want my gallery rows to be 100% in width and scale the image heights in each row accordingly keeping the aspect ratio.
The scenario is something like this:
On window load and resize:
1. Wrap each row into #div
2. Calculate image height for each row (overriding the initial fixed value)
Desired result
I was trying to find a pure CSS way, but looks like I can not get away without some JavaScript here.
EDIT: I was able to make this with some jQUery "mad skills":
codepen.io/ztm/pen/NGwaEL
$(document).ready(cascade);
$(window).on('resize',cascade);
function cascade() {
$('img').css({ 'height': 150 + "px" });
var wdth = $(".box").width();
var img_width = 0;
$('img').each(function() {
img_width += $(this).outerWidth( true );
if(img_width < wdth){
$(this).addClass('active');
$('.result').html('Ratio: '+wdth/img_width);
}
});
var ratio = (wdth-24)/img_width;
$('img').css({ 'height': 150*ratio + "px" });
}
It calculates a single row of image with initial height.
And so far the best solution to my problem I found was this:
miromannino.com/projects/justified-gallery/comment-page-4/
Based on your 'Desired result' link, it looks to me like you are wanting a Google+/Google Photos style gallery layout. In this style of gallery, images are added to a row until they fit the width of the row and then a new row is started.
The reason you can't get away with just css is that some trickery is needed to get images of various sizes to fit perfectly into the width of each row. The simplest solution to this is to add images until they exceed the width of the row, then crop all those images down to fit the row perfectly, that method is outlined in detail with jQuery and CSS here: Google+ Style Image Gallery
There are other methods you can use, like adding images until it is a certain percentage under the width of the row then scaling up the size of the images on that row so they fit perfectly, but the idea remains the same: add images until they are within a range of their parent container, then grow or shrink the images to make them the exact width.
Not sure if you are looking for this solution. Works fine in Chrome.
[1]: http://codepen.io/sridharspeaks/pen/meBwNN
You may look at the Isotope or Masonry plugins that could help you with this.

How can one find the "maximized" height of a browser window?

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

javascript jquery cycle rescale images to browser window BUT keeping aspect ratio

i have a php based site that needs to display images on the homepage that have arbitrary proportions. the requirement is to make them fill the browser window but to retain their aspect ratio.
for some reason i am having some trouble getting this to work using the jquery cycle plugin.
essentially the server-side code just pulls them from the db and pushes img elements into a div. i read the image sizes using php and write that to the alt element
then in my javascript code i have this:
$(document).ready(function() {
var window_h = $(window).height();
var window_w = $(window).width();
// sets the div that contains the jquery cycle images
$('#homepage-background-images').width(window_w);
$('#homepage-background-images').height(window_h);
$(window).resize(function() {
window_h = $(window).height();
window_w = $(window).width();
$('#homepage-background-images').width(window_w);
$('#homepage-background-images').height(window_h);
});
// homepage cycle
$('#homepage-background-images').cycle({
fx: 'fade',
speed: 5500,
fit: 1,
width: window_w,
height: window_h,
});
// ...
Obviously this isn't going to work since each image has a different aspect ratio, but I was wondering how one might pass serial aspect ratios into jquery cycle? These will always need to take the browser window size into consideration...
I have tried using the 'before' option on jquery, but it seems that you can't really affect the image properties there. I tried to use that to change the window_h variable based on a quick aspect ratio calculation but even updating that in my onBefore function seems to yield no result on the cycling images...
Any ideas? Is this tricky or am I just missing something obvious?
Thanks!
- J
If you use CSS max-width and max-height instance of HTML width and height it don't lose aspect ratio. Try adding style attribute to your image

Categories