kudago / waterfall

Waterfall layout. Extremely fast lightweight version of fluid columns masonry layout of isotope.
http://kudago.github.io/waterfall/
288 stars 67 forks source link

Is there any solution for re-layout when images loaded? #5

Closed shisoft closed 11 years ago

shisoft commented 11 years ago

I used to use a fixed height for each item, but still cannot fit my design, the height changes after waterfall took effect makes it looked bad. I am just wondering is there any possibility to observe height changes or image loaded for each item?

dy commented 11 years ago

Yeah, it's quite a trouble for this responsive layout I've faced with in the current project kudago.com. As far as we cannot detect server-side which image width is required for the current layout, in result I came up with passing img width/height as data-attributes, setting them to the images based on desired image width for the current column before new items being appended to the waterfall. Like this. Code is called before new items being added to the waterfall.

var items = documentFragmentWithNewItemsToAdd.childNodes,
container = document.getElementById("container-with-items"),
desiredImgWidth = container.firstChild.querySelector("img").clientWidth //TODO: calculated somehow for the current column width

for (var i = 0; i < items.length; i++){
    var img = items[i].querySelector("img");

    if (!img) continue;

    var origW = ~~img.getAttribute("data-width"),
        origH = ~~img.getAttribute("data-height"),
        ratio = origW/origH,
        height = desiredImgWidth / ratio;

    img.width = desiredImgWidth;
    img.height = height;

    //Remove hardcoded image width after load
    $(img).one("load", function(e){
        e.currentTarget.removeAttribute("width");
        e.currentTarget.removeAttribute("height");
    })
}
...
container.appendChild(documentFragmentWithNewItemsToAdd);

This code makes images fixed-height (that prevents waterfall to improperly place items) and waits them to load. The cost of this code is that each image will be rerendered after load. Will it work for you?

dy commented 11 years ago

Alternately, you can use imagesloaded jquery plugin, which fires load event once when all images in set load.

shisoft commented 11 years ago

Some of the image are not on my server, I don't know it's height before it have been loaded. I think the second option fits my needs, but how to refresh waterfall?

dy commented 11 years ago

You can call $(window).resize() or waterfall.reflow

var wfInstance = $(".container").waterfall()
wfInstance.reflow() 
shisoft commented 11 years ago

Great, It can do. Thank you.