I've done my homework and settled with a gem called
kaminari for pagination, and Masonry, a JS grid layout library. Due to the popularity of dynamic layouts, a lot of code examples are available. Based on those, my snippets look like so (in index.html.erb):<div class="masonry-container">
<% @contents.each do |content| %>
<div class="masonry-item">
<%= image_tag content.image.url(:original) %>
</div>
<% end %>
</div>
<%= paginate @contents %>
and in
application.js:$(function()
{
var $container = $('.masonry-container');
$container.masonry({
isFitWidth: true,
//columnWidth: '.masonry-item',
itemSelector: '.masonry-item'
}).imagesLoaded(function(){
$container.masonry('reload');
});
$container.infinitescroll({
navSelector : "nav.pagination",
nextSelector : "nav.pagination a[rel=next]",
itemSelector : ".masonry-container div.masonry-item",
},
function(newElements) {
var $newElems = $(newElements).css({opacity: 0});
$newElems.imagesLoaded(function(){
$newElems.animate({opacity: 1});
$container.masonry('appended', $newElems, true);
});
}
);
});
I was generally happy with the behavior of my scrolling except for several things.
- I wanted to center and distribute all images in the main container evenly, for which
Masonryprovides an optionisFitWidth: true. As I discovered, you can't use the optioncolumnWidthat the same time (that's why it is commented), as this combination appears to stack all images on top of each other. (I guess, I didn't read the documentation well enough but it took me some time to discover the cause). - The images I was loading differed in height quite a bit and perhaps for this reason they were not distributed as nicely as I wanted them to; there was too much white space vertically for my taste. Until I can find a better solution, I am settling with the following:
Paperclipgem for image uploading allows to serialize the image dimensions and to store them in the database;- One can create a scope, where the results will be sorted by height in a descending order. The scope will be used in controller to filter the results like so:
- As you scroll down and images are being loaded, you are supposed to be getting a message at the end of the current window saying something like "More images are being loaded....". My message somehow got attached to the top of the page, not the bottom. I wonder what combination of the CSS rules and/or other factors could be causing this behavior. In the meantime, I'm fixing the position of that element forcefully:
scope :by_height, -> { order('height DESC') }
@contents = Content.all.by_height.page(params[:page])
Sorting the images in descending order beforehand gave me the desired look: very nicely and tightly stacked images with much less white space in between.
#infscr-loading{
position:fixed;
bottom: 0;
}
In conclusion: that was fun.
No comments :
Post a Comment