gmaggio
7/5/2011 - 10:48 AM

Simple Horizontal Masonry

Simple Horizontal Masonry

/**
 * Builds a horizontal masonry in whats possbily (i haven't researched
 * the techniques) a crude manner.
 * Fits elements into columns if there is room and sets the width of
 * the container element to contain all the columns.
 * 
 * Known Issues:
 * - Does not do anything clever for elements where height exceeds 
 * window height (probably just gets chopped off if overflow: hidden)
 * - All elements are expected to be the column width
 * - Column count is wrong (misses off last one), added manual widths for now
 *
 * UPDATE 05/07/11 : Added gutterHeight
 * UPDATE 05/07/11 : Fixed issue of first item on some columns not having a gutter below it
 *
 */
function quickHorizontalMasonry() {

	var 
		columns = 0,
		positions = [],
		currentHeight = 0,
		columnWidth = 250,
		gutterWidth = 40,
		gutterHeight = 40,
		outerGutter = 40
	;

	$('#stream-scroll .overview').children().each(function() {

		var top;

		if (
			// if currentHeight is 0 the column is empty
			!currentHeight
			||
			// is there room
			(currentHeight + $(this).outerHeight()) < ($(window).height() - 60)
		) {
			// add to current column plus the horrizontal gutter
			top = currentHeight+=gutterHeight;
			currentHeight += $(this).outerHeight() ;
		} else {
			// add to new column
			columns++;
			top = gutterHeight;
			currentHeight = $(this).outerHeight()+gutterHeight;
		}

		// build array of positions
		positions.push({
			el: this,
			left: columns * (columnWidth + gutterWidth),
			top: top
		});
	});

	// set the container width --  issue having to add manual widths
	$('#stream-scroll .overview').css('width', ((columnWidth + gutterWidth) * columns) + columnWidth + gutterWidth + outerGutter);

	// go through positions array and set each position
	$.each(positions, function() {
		$(this.el).css({
			position: 'absolute',
			left: this.left+outerGutter,
			top: this.top
		});
	});
}