document.write('
')
/**
* photoset-grid - v1.0.0
* 2013-03-07
* jQuery plugin to arrange images into a flexible grid
* http://stylehatch.github.com/photoset-grid/
*
* Copyright 2013 Jonathan Moore - Style Hatch
*/
/*jshint browser: true, curly: true, eqeqeq: true, forin: false, immed: false, newcap: true, noempty: true, strict: true, undef: true, devel: true */
;(function ( $, window, document, undefined ) {
'use strict';
// Plugin name and default settings
var pluginName = "photosetGrid",
defaults = {
// Required
// set the width of the container
width : '100%',
// the space between the rows / columns
gutter : '0px',
// Optional
// wrap the images in a vs. div and link to the data-highres images
highresLinks : false,
// threshold for the lowres image, if container is > swap the data-highres
lowresWidth : 500,
// relational attr to apply to the links for lightbox use
rel : '',
// Call back events
onInit : function(){},
onComplete : function(){}
};
// Plugin constructor
function Plugin( element, options ) {
this.element = element;
this.options = $.extend( {}, defaults, options );
this._defaults = defaults;
this._name = pluginName;
this.init();
}
Plugin.prototype = {
init: function() {
// Call the optional onInit event set when the plugin is called
this.options.onInit();
this._setupRows(this.element, this.options);
this._setupColumns(this.element, this.options);
},
_callback: function(){
// Call the optional onComplete event after the plugin has been completed
this.options.onComplete();
},
_setupRows: function( elem, options ){
// Convert the layout string into an array to build the DOM structures
if(options.layout) {
// Check for layout defined in plugin call
this.layout = options.layout;
} else if($(elem).attr('data-layout')) {
// If not defined in the options, check for the data-layout attr
this.layout = $(elem).attr('data-layout');
} else {
// Otherwise give it a stacked layout (no grids for you)
// Generate a layout string of all ones based on the number of images
var stackedLayout = "";
var defaultColumns = 1;
for (var imgs=0; imgs<$(elem).find('img').length; imgs++ ) {
stackedLayout = stackedLayout + defaultColumns.toString();
}
this.layout = stackedLayout;
}
// Dump the layout into a rows array
// Convert the array into all numbers vs. strings
this.rows = this.layout.split('');
for (var i in this.rows ) {
this.rows[i] = parseInt(this.rows[i], 10);
}
var $images = $(elem).find('img');
var imageIndex = 0;
$.each(this.rows, function(i, val){
var rowStart = imageIndex;
var rowEnd = imageIndex + val;
// Wrap each set of images in a row into a container div
$images.slice(rowStart, rowEnd).wrapAll('
');
imageIndex = rowEnd;
});
$(elem).find('.photoset-row:not(:last-child)').css({
'margin-bottom': options.gutter
});
},
_setupColumns: function( elem, options ){
// Reference to this Plugin
var $this = this;
var setupStyles = function(){
var $rows = $(elem).find('.photoset-row');
var $images = $(elem).find('img');
// Wrap the images in links to the highres or regular image
// Otherwise wrap in div.photoset-cell
if(options.highresLinks){
$images.each(function(){
var highres;
// If a highres image exists link it up!
if($(this).attr('data-highres')){
highres = $(this).attr('data-highres');
} else {
highres = $(this).attr('src');
}
$(this).wrapAll('');
});
// Apply the optional rel
if(options.rel){
$images.parent().attr('rel', options.rel);
}
} else {
$images.each(function(){
$(this).wrapAll('');
});
}
var $cells = $(elem).find('.photoset-cell');
var $cols1 = $(elem).find('.cols-1 .photoset-cell');
var $cols2 = $(elem).find('.cols-2 .photoset-cell');
var $cols3 = $(elem).find('.cols-3 .photoset-cell');
var $cols4 = $(elem).find('.cols-4 .photoset-cell');
var $cols5 = $(elem).find('.cols-5 .photoset-cell');
// Apply styles initial structure styles to the grid
$(elem).css({
'width': options.width
});
$rows.css({
'clear': 'left',
'display': 'block',
'overflow': 'hidden'
});
$cells.css({
'float': 'left',
'display': 'block',
'line-height': '0',
'-webkit-box-sizing': 'border-box',
'-moz-box-sizing': 'border-box',
'box-sizing': 'border-box'
});
$images.css({
'width': '100%',
'height': 'auto'
});
// Set the width of the cells based on the number of columns in the row
$cols1.css({ 'width': '100%' });
$cols2.css({ 'width': '50%' });
$cols3.css({ 'width': '33.3%' });
$cols4.css({ 'width': '25%' });
$cols5.css({ 'width': '20%' });
var gutterVal = parseInt(options.gutter, 10);
// Apply 50% gutter to left and right
// this provides equal gutters a high values
$(elem).find('.photoset-cell:not(:last-child)').css({
'padding-right': (gutterVal / 2) + 'px'
});
$(elem).find('.photoset-cell:not(:first-child)').css({
'padding-left': (gutterVal / 2) + 'px'
});
function resizePhotosetGrid(){
// Give the values a floor to prevent misfires
var w = $(elem).width().toString();
if( w !== $(elem).attr('data-width') ) {
$rows.each(function(){
var $shortestImg = $(this).find('img:eq(0)');
$(this).find('img').each(function(){
var $img = $(this);
if( $img.height() < $shortestImg.height() ){
$shortestImg = $(this);
}
if($img.width() > options.lowresWidth && $img.attr('data-highres')){
$img.attr('src', $img.attr('data-highres'));
}
});
var rowHeight = $shortestImg.height();
// Adding a buffer to shave off a few pixels in height
var bufferHeight = Math.floor(rowHeight * 0.025);
$(this).height( rowHeight - bufferHeight );
$(this).find('img').each(function(){
var marginOffset = ((rowHeight - $(this).height())*0.5) + 'px';
$(this).css({
'margin-top' : marginOffset
});
});
});
$(elem).attr('data-width', w );
}
}
resizePhotosetGrid();
$(window).on("resize", function() {
resizePhotosetGrid();
});
};
$(elem).imagesLoaded(function(){
setupStyles();
// Call _callback which calls the optional onComplete
$this._callback();
});
}
};
// plugin wrapper around the constructor
$.fn[pluginName] = function ( options ) {
return this.each(function () {
if (!$.data(this, "plugin_" + pluginName)) {
$.data(this, "plugin_" + pluginName, new Plugin( this, options ));
}
});
};
/*!
* jQuery imagesLoaded plugin v2.1.1
* http://github.com/desandro/imagesloaded
*
* MIT License. by Paul Irish et al.
*/
/*jshint curly: true, eqeqeq: true, noempty: true, strict: true, undef: true, browser: true */
/*global jQuery: false */
// blank image data-uri bypasses webkit log warning (thx doug jones)
var BLANK = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==';
$.fn.imagesLoaded = function( callback ) {
var $this = this,
deferred = $.isFunction($.Deferred) ? $.Deferred() : 0,
hasNotify = $.isFunction(deferred.notify),
$images = $this.find('img').add( $this.filter('img') ),
loaded = [],
proper = [],
broken = [];
// Register deferred callbacks
if ($.isPlainObject(callback)) {
$.each(callback, function (key, value) {
if (key === 'callback') {
callback = value;
} else if (deferred) {
deferred[key](value);
}
});
}
function doneLoading() {
var $proper = $(proper),
$broken = $(broken);
if ( deferred ) {
if ( broken.length ) {
deferred.reject( $images, $proper, $broken );
} else {
deferred.resolve( $images );
}
}
if ( $.isFunction( callback ) ) {
callback.call( $this, $images, $proper, $broken );
}
}
function imgLoadedHandler( event ) {
imgLoaded( event.target, event.type === 'error' );
}
function imgLoaded( img, isBroken ) {
// don't proceed if BLANK image, or image is already loaded
if ( img.src === BLANK || $.inArray( img, loaded ) !== -1 ) {
return;
}
// store element in loaded images array
loaded.push( img );
// keep track of broken and properly loaded images
if ( isBroken ) {
broken.push( img );
} else {
proper.push( img );
}
// cache image and its state for future calls
$.data( img, 'imagesLoaded', { isBroken: isBroken, src: img.src } );
// trigger deferred progress method if present
if ( hasNotify ) {
deferred.notifyWith( $(img), [ isBroken, $images, $(proper), $(broken) ] );
}
// call doneLoading and clean listeners if all images are loaded
if ( $images.length === loaded.length ) {
setTimeout( doneLoading );
$images.unbind( '.imagesLoaded', imgLoadedHandler );
}
}
// if no images, trigger immediately
if ( !$images.length ) {
doneLoading();
} else {
$images.bind( 'load.imagesLoaded error.imagesLoaded', imgLoadedHandler )
.each( function( i, el ) {
var src = el.src;
// find out if this image has been already checked for status
// if it was, and src has not changed, call imgLoaded on it
var cached = $.data( el, 'imagesLoaded' );
if ( cached && cached.src === src ) {
imgLoaded( el, cached.isBroken );
return;
}
// if complete is true and browser supports natural sizes, try
// to check for image status manually
if ( el.complete && el.naturalWidth !== undefined ) {
imgLoaded( el, el.naturalWidth === 0 || el.naturalHeight === 0 );
return;
}
// cached images don't fire load sometimes, so we reset src, but only when
// dealing with IE, or image is complete (loaded) and failed manual check
// webkit hack from http://groups.google.com/group/jquery-dev/browse_thread/thread/eee6ab7b2da50e1f
if ( el.readyState || el.complete ) {
el.src = BLANK;
el.src = src;
}
});
}
return deferred ? deferred.promise( $this ) : $this;
};
/*
* throttledresize: special jQuery event that happens at a reduced rate compared to "resize"
*
* latest version and complete README available on Github:
* https://github.com/louisremi/jquery-smartresize
*
* Copyright 2012 @louis_remi
* Licensed under the MIT license.
*
* This saved you an hour of work?
* Send me music http://www.amazon.co.uk/wishlist/HNTU0468LQON
*/
var $event = $.event,
$special,
dummy = {_:0},
frame = 0,
wasResized, animRunning;
$special = $event.special.throttledresize = {
setup: function() {
$( this ).on( "resize", $special.handler );
},
teardown: function() {
$( this ).off( "resize", $special.handler );
},
handler: function( event, execAsap ) {
// Save the context
var context = this,
args = arguments;
wasResized = true;
if ( !animRunning ) {
setInterval(function(){
frame++;
if ( frame > $special.threshold && wasResized || execAsap ) {
// set correct event type
event.type = "throttledresize";
$event.dispatch.apply( context, args );
wasResized = false;
frame = 0;
}
if ( frame > 9 ) {
$(dummy).stop();
animRunning = false;
frame = 0;
}
}, 30);
animRunning = true;
}
},
threshold: 0
};
})( jQuery, window, document );