Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pinterest like layout cellH: 'auto' #20

Closed
Kyojimaru opened this issue Dec 19, 2013 · 28 comments
Closed

Pinterest like layout cellH: 'auto' #20

Kyojimaru opened this issue Dec 19, 2013 · 28 comments

Comments

@Kyojimaru
Copy link

Hi,

I have been using your script to make a pinterest like layout. I have used it with no problem if it's the first time the image is loaded, but if the windows is resized, some height of the '.brick' went wrong so some text under the image is outside the '.brick' and sometimes collide with the other below it.

@kombai
Copy link
Owner

kombai commented Dec 19, 2013

Could you give me the link for view please ?

@Kyojimaru
Copy link
Author

you can use the demo that you provided here :
http://vnjs.net/www/project/freewall/example/pinterest-layout.html
try to minimize the windows to half the screen size then maximize it again, and the result will be like this

pinterest-layout

@kombai
Copy link
Owner

kombai commented Dec 19, 2013

got it, will fix soon.

@PreechaJ
Copy link

Hi, I just notice this problem today after I upgrade to 1.03, too.
I think 1.02 works without this problem.

Also, append items to pinterest layout brokens.

I have try to change line 592, as a workaround for now.

//Calculate block height from item's actual height, not form free area's.
if('auto' != setting.cellH) {
// for fitZone;
block.height = Math.min(block.height, freeArea.height);
}

Please note look like this work for me, not well test though.

@Kyojimaru
Copy link
Author

@PreechaJ it's working better if you change that line, but the same problem still occurs when given the same treatment ( minimize windows > reduce windows width until half of screen width > maximize it again )

@kombai
Copy link
Owner

kombai commented Dec 19, 2013

Ok just fixed it by release the height of block before get it again.
see it line 79
https://github.com/kombai/freewall/blob/master/freewall.js#L79

@Kyojimaru
Copy link
Author

thanks for the fix, it works perfectly, but now I have another issue, for some image the padding for the .info doesn't work.
here's the screenshot :
pinterest-info-padding

@kombai
Copy link
Owner

kombai commented Dec 19, 2013

For .infor you can using position: absolute, bottom: 20px;

@Kyojimaru
Copy link
Author

can't use it. When I add position: absolute, bottom: 20px; to '.info' class, the text will appear 20px from the bottom of the image, '.brick' height will be the same with '.info' height if I add the position: absolute

@kombai
Copy link
Owner

kombai commented Dec 19, 2013

you can wrap the text in a div, then set it with bottom: 0px;

@kombai kombai closed this as completed Dec 20, 2013
@Kyojimaru
Copy link
Author

Hi, sorry for my late reply, I was sick before.
I have wrapped my text in div '.info', and I have succedded to make the margin for the text by changing the '.info' position to relative before fitWidth() and change it to absolute after the fitWidth() is finished.
But there's still some unknown gap between the image and the div '.info'

I tried to show the image only, and there's a gap in the bottom of '.brick' with the image for some of the image
pinterest-gap
is it possible to remove those gap?

@kombai
Copy link
Owner

kombai commented Dec 23, 2013

yes, you can using event onShowBlock to reset the image height.

wall.addCustomEvent("onShowBlock", function() {

$(this).find("img").height($(this).height());

});

@kombai
Copy link
Owner

kombai commented Dec 26, 2013

Hello,
Freewall have next update for fix this issue, please check it.
Best

@PreechaJ
Copy link

Really cool!
I just try this version and it works perfectly.
This version also solves my previous problem when I try to append more items to pinterest layout, too.

@Kyojimaru
Copy link
Author

@kombai thanks, for the fix.

by the way is it possible to add a feature like infinite scroll / load more button?
I've been using a repeater inside an update panel for this, for the first load it looks perfect, but after I click the load more link, the image didn't fit the width of the container, it just stacking below the other image.
I have added ewall.fitWidth(); when the update process finished, but the problem still persist

@PreechaJ can you share what did you use to append more items to pinterest layout? I've been searching for it for about 4 days, but still don't know what to do

@kombai
Copy link
Owner

kombai commented Dec 27, 2013

@Kyojimaru, before arrange layout you must let the image loaded first, same I did here:

                        var images = wall.container.find('.brick');
                        var length = images.length;
                        images.css({visibility: 'hidden'});
                        images.find('img').load(function() {
                                -- length;
                                if (!length) {
                                        setTimeout(function() {
                                                images.css({visibility: 'visible'});
                                                wall.fitWidth();
                                        }, 505);
                                }
                        });

@Kyojimaru
Copy link
Author

I see, i just found that one but by recalling the whole code for Pinterest Layout, I'll try it again with just the image.load only.
But I want to show the added item after the images is loaded, how can I get to know if the image is the 1st until the 20nd and so on? or how to get the data-delay?

@kombai
Copy link
Owner

kombai commented Dec 27, 2013

the order index stored at the id attribute or data-delay too.

wall.addCustomEvent("onBlockLoad", function() {
   console.log($(this).attr("data-delay"));
});

@Kyojimaru
Copy link
Author

is it possible to get the "data-delay" before the

images.find('img').load(function() {});

I don't know how to use the id because the first time it loaded, the id is "1-2 until 20-2" and the next time it loaded it's "1-3 until 40-3"

Edit : I need to make the visible of the new set of images (eg: 21th - 40th image) to hidden and the 1st - 20th keep visible until the the image is loaded and made all the images visible

I've tried to use this :

images.find('img').on('load', function () {
  alert(images.attr('id'));
  --length;
    if (!length) {
      setTimeout(function () {
      images.css({ visibility: 'visible' });
      $('.info').css({ position: 'relative' });
      ewall.fitWidth();
      $('.info').css({ position: 'absolute' });
    }, 505);
  }
});

but the alert keep showing "1-3"

@kombai
Copy link
Owner

kombai commented Dec 27, 2013

you can't get it before append to layout. Btw, when you using onBlockLoad you can control it.
The time line of events:

  • onGridReady => the layout finish to estimate unit/ total rows, total columns.
  • onBlockLoad => happend when earch block adjusted size base on unit width/ unit height.
  • onGridLoad => all block adjusted
  • onGridArrange => when all block arrange to layout, but them still haven't show up
  • onBlockShow => for each block show up, right now you can see it on web page
  • onGridShow => when all blocks show up.

About the format id: first number- second number
the first number is the index of block on layout.
the second number is the instance number of freewall. You don't need using this, I using for support more than Freewall on one web page.

@Kyojimaru
Copy link
Author

thanks for the help, now it's working like what I want,
and if you can, maybe you want to add this code

images.find('img').on('error', function () {
    --length;
});

before

images.find('img').load

to prevent the image not showing if by chance there's any image with error link

@Kyojimaru
Copy link
Author

hi, I've got another question. I have changed my code to use your

wall.appendBlock(html)

command, did the image will be reloaded every time a new item is appended? because the more I append the image, the longer it take to load. and if it will always be reloaded every time I append new item, are there any workaround for this?

@kombai
Copy link
Owner

kombai commented Dec 27, 2013

no, infact you need add html to DOM first, wait for image loaded then using wall.appendBlock(items). Or you can pre set width/ height of image.

@PreechaJ
Copy link

The pinterest layout need special logic to work with. So wall.appendBlock(html) alone can't do the job.

In other layout, freewall can calculates and adjust items' size by determine setting you pass to reset(), but with pinterest layout, freewall has no idea how tall each item is before image already loaded, so what you have to do is to monitor for all images to be loaded before telling freewall to refresh it layout.

See how the link with id 'add-more' works here.

http://jsfiddle.net/X9DZz/7/

Hope this help.

P.S. I don't hide image first, because I don't want to make user wait for long time for all images to loaded before show.
I prefer the animation while items rearrange them self, you can also make some animate gif image holder first and then replace it with your real image after loaded.
I just do it base on pinterest example, you can easily load your items by jquery ajax.

@Kyojimaru
Copy link
Author

@PreechaJ thanks for the help 😄 , now it's working better than before. btw, what is the meaning of

var brick = $('html');

at the getBrick, and how does it differ with the plain html?

@blackzabaha
Copy link

http://api.jquery.com/jQuery/#jQuery2
It is the way to create dom on the fly, if you don't already know, and then you can do jQuery magic with the result it return.

It should works both way, but if you concern for performance, then I'm sorry I really don't know which one is better.

It just about creating dom on the fly for many pieces and then sum up for the final result you want at loadMoreBricks().
or just create only string at the getBrick(), and then sum up strings and pass it to $(html) only once at loadMoreBricks() to create final result if you want.

Any way, that is just an example. In real life, you might load your html via ajax, then your best approach should be like this:

$.get(url, function(html) {
var allBricks = $(html); // You should already return the whole html of bricks here, so just do this.

//Add onLoad & onError handler to wait for all images within allBricks loaded, append to freewall, refresh layout like I do in previous example.
});

@andrewhowardim
Copy link

Hi kombai,

I'm trying to load Instafeed into Freewall any advice

@pushpendrayadav1996
Copy link

layout disorderd after removing images+
capture

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants