diff options
Diffstat (limited to 'static/js')
| -rw-r--r-- | static/js/jquery.masonry.js | 308 |
1 files changed, 308 insertions, 0 deletions
diff --git a/static/js/jquery.masonry.js b/static/js/jquery.masonry.js new file mode 100644 index 0000000..fbf8425 --- /dev/null +++ b/static/js/jquery.masonry.js @@ -0,0 +1,308 @@ +/************************************************* +** jQuery Masonry version 1.2.0 +** copyright David DeSandro, licensed GPL & MIT +** http://desandro.com/resources/jquery-masonry +**************************************************/ +;(function($){ + + /*! + * smartresize: debounced resize event for jQuery + * http://github.com/lrbabe/jquery-smartresize + * + * Copyright (c) 2009 Louis-Remi Babe + * Licensed under the GPL license. + * http://docs.jquery.com/License + * + */ + var event = $.event, + resizeTimeout; + + event.special[ "smartresize" ] = { + setup: function() { + $( this ).bind( "resize", event.special.smartresize.handler ); + }, + teardown: function() { + $( this ).unbind( "resize", event.special.smartresize.handler ); + }, + handler: function( event, execAsap ) { + // Save the context + var context = this, + args = arguments; + + // set correct event type + event.type = "smartresize"; + + if(resizeTimeout) + clearTimeout(resizeTimeout); + resizeTimeout = setTimeout(function() { + jQuery.event.handle.apply( context, args ); + }, execAsap === "execAsap"? 0 : 100); + } + }; + + $.fn.smartresize = function( fn ) { + return fn ? this.bind( "smartresize", fn ) : this.trigger( "smartresize", ["execAsap"] ); + }; + + + + // masonry code begin + $.fn.masonry = function(options, callback) { + + function getBricks(props, opts) { + props.$bricks = opts.itemSelector == undefined ? + opts.$brickParent.children() : + opts.$brickParent.find(opts.itemSelector); + } + + function placeBrick($brick, setCount, setY, setSpan, props, opts) { + var shortCol = 0; + + for ( i=0; i < setCount; i++ ) { + if ( setY[i] < setY[ shortCol ] ) shortCol = i; + } + + var position = { + left: props.colW * shortCol + props.posLeft, + top: setY[ shortCol ] + }; + + + if( props.masoned && opts.animate ) { + $brick.animate( position, { + duration: opts.animationOptions.duration, + easing: opts.animationOptions.easing, + complete: opts.animationOptions.complete, + step: opts.animationOptions.step, + queue: opts.animationOptions.queue, + specialEasing: opts.animationOptions.specialEasing + }); + } else { + $brick.css(position); + } + + for ( i=0; i < setSpan; i++ ) { + props.colY[ shortCol + i ] = setY[ shortCol ] + $brick.outerHeight(true) ; + } + }; + + + function masonrySetup($wall, opts, props) { + getBricks(props, opts); + + if ( opts.columnWidth == undefined) { + props.colW = props.masoned ? + $wall.data('masonry').colW : + props.$bricks.outerWidth(true); + } else { + props.colW = opts.columnWidth; + } + + props.colCount = Math.floor( $wall.width() / props.colW ) ; + props.colCount = Math.max( props.colCount, 1 ); + }; + + + function masonryArrange($wall, opts, props) { + // if masonry hasn't been called before + if( !props.masoned ) $wall.css( 'position', 'relative' ); + + if ( !props.masoned || opts.appendedContent != undefined ) { + // just the new bricks + props.$bricks.css( 'position', 'absolute' ); + } + + // get top left position of where the bricks should be + var cursor = $('<div />'); + $wall.prepend( cursor ); + props.posTop = Math.round( cursor.position().top ); + props.posLeft = Math.round( cursor.position().left ); + cursor.remove(); + + // set up column Y array + if ( props.masoned && opts.appendedContent != undefined ) { + // if appendedContent is set, use colY from last call + props.colY = $wall.data('masonry').colY; + + /* + * in the case that the wall is not resizeable, + * but the colCount has changed from the previous time + * masonry has been called + */ + for (i= $wall.data('masonry').colCount; i < props.colCount; i++) { + props.colY[i] = props.posTop; + }; + + } else { + props.colY = []; + for ( i=0; i < props.colCount; i++) { + props.colY[i] = props.posTop; + } + } + + + // layout logic + if ( opts.singleMode ) { + props.$bricks.each(function(){ + var $brick = $(this); + placeBrick($brick, props.colCount, props.colY, 1, props, opts); + }); + } else { + props.$bricks.each(function() { + var $brick = $(this); + + //how many columns does this brick span + var colSpan = Math.ceil( $brick.outerWidth(true) / props.colW); + colSpan = Math.min( colSpan, props.colCount ); + + + if ( colSpan == 1 ) { + // if brick spans only one column, just like singleMode + placeBrick($brick, props.colCount, props.colY, 1, props, opts); + } else { + // brick spans more than one column + + //how many different places could this brick fit horizontally + var groupCount = props.colCount + 1 - colSpan; + var groupY = [0]; + // for each group potential horizontal position + for ( i=0; i < groupCount; i++ ) { + groupY[i] = 0; + // for each column in that group + for ( j=0; j < colSpan; j++ ) { + // get the maximum column height in that group + groupY[i] = Math.max( groupY[i], props.colY[i+j] ); + } + } + + placeBrick($brick, groupCount, groupY, colSpan, props, opts); + } + }); // /props.bricks.each(function() { + } // /layout logic + + // set the height of the wall to the tallest column + props.wallH = 0; + for ( i=0; i < props.colCount; i++ ) { + props.wallH = Math.max( props.wallH, props.colY[i] ); + } + var wallCSS = { height: props.wallH - props.posTop }; + // $wall.height( props.wallH - props.posTop ); + if ( props.masoned && opts.animate ) { + $wall.animate(wallCSS, { + duration: opts.animationOptions.duration, + easing: opts.animationOptions.easing, + complete: opts.animationOptions.complete, + step: opts.animationOptions.step, + queue: opts.animationOptions.queue, + specialEasing: opts.animationOptions.specialEasing + }); + } else { + $wall.css(wallCSS); + } + + // add masoned class first time around + if ( !props.masoned ) $wall.addClass('masoned'); + + // provide props.bricks as context for the callback + callback.call( props.$bricks ); + + // set all data so we can retrieve it for appended appendedContent + // or anyone else's crazy jquery fun + $wall.data('masonry', props ); + + + }; // /masonryArrange function + + + function masonryResize($wall, opts, props) { + props.masoned = $wall.data('masonry') != undefined; + var prevColCount = $wall.data('masonry').colCount; + masonrySetup($wall, opts, props); + if ( props.colCount != prevColCount ) masonryArrange($wall, opts, props); + }; + + + /* + * let's begin + * IN A WORLD... + */ + return this.each(function() { + + var $wall = $(this); + + var props = $.extend( {}, $.masonry ); + + // checks if masonry has been called before on this object + props.masoned = $wall.data('masonry') != undefined; + + var previousOptions = props.masoned ? $wall.data('masonry').options : {}; + + var opts = $.extend( + {}, + props.defaults, + previousOptions, + options + ); + + // should we save these options for next time? + props.options = opts.saveOptions ? opts : previousOptions; + + //picked up from Paul Irish + callback = callback || function(){}; + + + if ( props.masoned && opts.appendedContent != undefined ) { + // if we're dealing with appendedContent + opts.$brickParent = opts.appendedContent; + } else { + opts.$brickParent = $wall; + } + + getBricks(props, opts); + + + if ( props.$bricks.length ) { + // call masonry layout + masonrySetup($wall, opts, props); + masonryArrange($wall, opts, props); + + // binding window resizing + var resizeOn = previousOptions.resizeable; + if ( !resizeOn && opts.resizeable ) { + $(window).bind('smartresize.masonry', function() { masonryResize($wall, opts, props); } ); + } + if ( resizeOn && !opts.resizeable ) $(window).unbind('smartresize.masonry'); + } else { + // brickParent is empty, do nothing, go back home and eat chips + return this; + } + + }); // /return this.each(function() + }; // /$.fn.masonry = function(options) + + + + $.masonry = { + defaults : { + singleMode: false, + columnWidth: undefined, + itemSelector: undefined, + appendedContent: undefined, + saveOptions: true, + resizeable: true, + animate: false, + animationOptions: {} + }, + colW: undefined, + colCount: undefined, + colY: undefined, + wallH: undefined, + masoned: undefined, + posTop: 0, + posLeft: 0, + options: undefined, + $bricks: undefined, + $brickParent: undefined + }; + +})(jQuery);
\ No newline at end of file |
