Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JS/jQuery fit all images inside div (without whitespace)

I have a div call it #container, Inside this #container I have n amount of img tags call it images n can be 2, 10, 40 and so on. I am wondering how I can fit n amount of images inside a #container to close all white spaces stretch the images. Quality doesn't matter This is what I tried until now:

var amount = $("#container > img").length;
var amount_w = amount*200; //200 width of 1 image 
var amount_h = amount*130; //120 height  image 
var refH = $("#container").height();
var refW = $("#container").width();

var refRatio = refW/refH;
$("#container img").each(function(){
     $(this).height((amount_h-130)-refH);
     $(this).width((amount_w-230)-refW);
});
like image 959
Froxz Avatar asked Jan 25 '16 15:01

Froxz


2 Answers

First of all, it IS possible to achieve what you need even while maintaining the aspect ratio of the images - however the row height will be calculated, but it is not a trivial task (well, at least not as trivial as a single line formula).

There is a jQuery plugin called jPictura which I have developed. I believe the plugin does exactly what you need.

Here is a working fiddle.

You can find the plugin source codes and documentation on GitHub.

Simple example how to use the plugin:

$(document).ready(function () {
    $('#my-gallery').jpictura({
        layout: { itemSpacing: 0, justifyLastRow: true, idealRowHeight: 200}
    });
});
  • itemSpacing - amount of space between the images in pixels
  • justifyLastRow - if true, the images in last row will be stretched to take the full width of the row
  • idealRowHeight - The desired height of the rows in pixels. The plugin will do its best to arrange the items so the row heights are as close as possible to this value.
  • there are a lot more options documented on GitHub

Beside the JS stuff that calculates the correct widths and heights of the images, there is one more thing to be considered regarding the blank space between images. Images are by default inline-blocks which means they behave like words and words do have some white space inbetween, right? Make them display: block; float: left; or use the flex box layout to get rid of the blank space. The plugin uses float: left; by default.

like image 171
Anton Avatar answered Nov 15 '22 00:11

Anton


I created something that might interest you

var container = $('#container');
var height = container.outerHeight();
var width = container.outerWidth();

function populate(n){
    var rem_items = n;
    var rows = Math.round(Math.sqrt(n));
    var row_items = Math.ceil(n/rows);

    for (var i=0; i<rows; i++){

        // this prevents us from generating a lonely single box in a row
        if( (rem_items%(rows-i))===0 ){
            row_items = rem_items/(rows-i);
        }

        if(rem_items<row_items){
            row_items = rem_items;
        }

        rem_items = rem_items-row_items;

        for (var j=0; j<row_items; j++){
            var img_height = height/rows;
            var img_width = width/row_items;
            var img_left = j*img_width;
            var img_top = i*img_height;
            var img = $('<div class="cell"></div>');
            img.css({
                width: img_width,
                height: img_height,
                left: img_left,
                top: img_top
            });
            container.append(img);
        }
    }
}

populate(40);

https://jsfiddle.net/jLq4hgaa/1/

Basically, it calculates the "most balanced" distribution of the images horizontally and vertically.

It does what you're asking for in the plainest sense. It distributes images/containers inside a container evenly regardless of aspect ratio.

like image 35
DigitalDouble Avatar answered Nov 15 '22 00:11

DigitalDouble