@ -56,8 +56,8 @@
} ,
} ,
_filterFind : function ( selector ) {
_filterFind : function ( $elems , selector ) {
return selector ? this . find ( selector ) . add ( thi s. find ( selector ) ) : thi s;
return selector ? $elems . filter ( selector ) . add ( $elem s. find ( selector ) ) : $elem s;
} ,
} ,
// sets up widget
// sets up widget
@ -70,7 +70,7 @@
this . styleQueue = [ ] ;
this . styleQueue = [ ] ;
this . elemCount = 0 ;
this . elemCount = 0 ;
// need to get atoms
// need to get atoms
this . atoms . $all = this . $elem . children ( ) . molequul ( '_filterFind' , this . options . itemSelector ) ;
this . atoms . $all = this . _filterFind ( this . $elem . children ( ) , this . options . itemSelector ) ;
// console.log( 'all atoms', this.atoms.$all.length )
// console.log( 'all atoms', this.atoms.$all.length )
@ -97,16 +97,19 @@
this . usingTransforms = Modernizr . csstransforms && Modernizr . csstransitions && ! jQueryAnimation ;
this . usingTransforms = Modernizr . csstransforms && Modernizr . csstransitions && ! jQueryAnimation ;
this . positionFn = this . usingTransforms ? Molequul . translate : Molequul . positionAbs ;
this . positionFn = this . usingTransforms ? this . _translate : this . _ positionAbs;
// sorting
// sorting
var originalOrderSorter = {
var originalOrderSorter = {
'original-order' : function ( $elem ) {
'original-order' : function ( $elem ) {
return prop s. elemCount ;
return thi s. elemCount ;
}
}
} ;
} ;
this . options . getSortData = $ . extend ( originalOrderSorter , this . options . getSortData ) ;
this . options . getSortData = $ . extend ( originalOrderSorter , this . options . getSortData ) ;
this . _setupAtoms ( this . atoms . $all ) ;
this . atoms . $all . molequul ( '_setupAtoms' ) ;
this . atoms . $all . molequul ( '_setupAtoms' ) ;
@ -118,10 +121,9 @@
$cursor . remove ( ) ;
$cursor . remove ( ) ;
// add molequul class first time around
// add molequul class first time around
var $container = this . $elem ,
var instance = this ;
containerClass = this . options . containerClass ;
setTimeout ( function ( ) {
setTimeout ( function ( ) {
$container . addClass ( containerClass ) ;
instance . $elem . addClass ( instance . options . containerClass ) ;
} , 0 ) ;
} , 0 ) ;
// console.log( this.options.layoutMode )
// console.log( this.options.layoutMode )
@ -133,17 +135,57 @@
// save data
// save data
// this.data( 'molequul', props );
// this.data( 'molequul', props );
// bind resize method
if ( this . options . resizeable ) {
$ ( window ) . bind ( 'smartresize.molequul' , function ( ) { instance . $elem . molequul ( 'resize' ) } ) ;
}
} ,
_isNewProp : function ( prop ) {
return this . prevOpts ? ( this . options [ prop ] !== this . prevOpts [ prop ] ) : true ;
} ,
} ,
// _init fires when your instance is first created
// _init fires when your instance is first created
// (from the constructor above), and when you
// (from the constructor above), and when you
// attempt to initialize the widget again (by the bridge)
// attempt to initialize the widget again (by the bridge)
// after it has already been initialized.
// after it has already been initialized.
_init : function ( ) {
_init : function ( callback ) {
// this.options = $.extend( true, Molequul.options, this.options );
// this.options = $.extend( true, Molequul.options, this.options );
console . log ( this )
// check if watched properties are new
var instance = this ;
$ . each ( [ 'filter' , 'sortBy' , 'sortDir' ] , function ( i , propName ) {
// console.log( propName, this );
instance . isNew [ propName ] = instance . _isNewProp ( propName ) ;
} ) ;
if ( this . isNew . filter ) {
this . atoms . $filtered = this . _filter ( this . atoms . $all )
} else {
this . atoms . $filtered = this . atoms . $all ;
}
if ( this . isNew . filter || this . isNew . sortBy || this . isNew . sortDir ) {
this . _sort ( ) ;
}
// console.log( '_' + this.options.layoutMode + 'ResetLayoutProps' )
// this[ '_' + this.options.layoutMode + 'ResetLayoutProps' ]();
// console.log( $.data( this.$elem, 'molequul') );
// setTimeout( function(){
// this.layout( this.atoms.$filtered, callback );
this . reLayout ( callback ) ;
// instance.$elem.molequul( 'layout', instance.atoms.$filtered, callback );
// }, 0)
// console.log( this )
// init code
// init code
} ,
} ,
@ -171,21 +213,15 @@
isNewProp : function ( property , props ) {
if ( ! props . initialized ) {
return true ;
}
var previousProp = props . prevOpts [ property ] ;
return ( props . opts [ property ] !== previousProp ) ;
} ,
// ====================== Adding ======================
// ====================== Adding ======================
addSortData : function ( props ) {
_addSortData : function ( $atoms ) {
return this . each ( function ( ) {
var instance = this ;
$atoms . each ( function ( ) {
var $this = $ ( this ) ,
var $this = $ ( this ) ,
sortData = { } ,
sortData = { } ,
getSortData = props . opts . getSortData ,
getSortData = instance . option s . getSortData ,
key ;
key ;
// get value for sort data based on fn( $elem ) passed in
// get value for sort data based on fn( $elem ) passed in
for ( key in getSortData ) {
for ( key in getSortData ) {
@ -194,58 +230,63 @@
// apply sort data to $element
// apply sort data to $element
$this . data ( 'molequul-sort-data' , sortData ) ;
$this . data ( 'molequul-sort-data' , sortData ) ;
// increment element count
// increment element count
props . elemCount ++ ;
instance . elemCount ++ ;
} ) ;
} ) ;
} ,
} ,
setupAtoms : function ( props ) {
_setupAtoms : function ( $atoms ) {
// base style for atoms
// base style for atoms
var atomStyle = { position : 'absolute' } ;
var atomStyle = { position : 'absolute' } ;
if ( prop s. usingTransforms ) {
if ( thi s. usingTransforms ) {
atomStyle . left = 0 ;
atomStyle . left = 0 ;
atomStyle . top = 0 ;
atomStyle . top = 0 ;
}
}
$atoms . css ( atomStyle ) ;
// add sort data to each elem
// add sort data to each elem
return this . molequul ( 'addSortData' , props ) . css ( atomStyle ) ;
this . _addSortData ( $atoms ) ;
// return this.molequul( 'addSortData', props ).css( atomStyle );
} ,
} ,
// ====================== Filtering ======================
// ====================== Filtering ======================
filter : function ( $atoms ) {
_ filter : function ( $atoms ) {
var props = this . data ( 'molequul' ) ,
var $filteredAtoms ,
filter = prop s. opts . filter === '' ? '*' : prop s. opts . filter ;
filter = thi s. option s . filter === '' ? '*' : thi s. option s . filter ;
if ( ! filter ) {
if ( ! filter ) {
props . atoms . $filtered = $atoms ;
$filteredAtoms = $atoms ;
} else {
} else {
var hiddenClass = prop s. opts . hiddenClass ,
var hiddenClass = thi s. option s . hiddenClass ,
hiddenSelector = '.' + hiddenClass ,
hiddenSelector = '.' + hiddenClass ,
$visibleAtoms = $atoms . not ( hiddenSelector ) ,
$visibleAtoms = $atoms . not ( hiddenSelector ) ,
$hiddenAtoms = $atoms . filter ( hiddenSelector ) ,
$hiddenAtoms = $atoms . filter ( hiddenSelector ) ,
$atomsToShow = $hiddenAtoms ;
$atomsToShow = $hiddenAtoms ;
props . atoms . $filtered = $atoms . filter ( filter ) ;
$filteredAtoms = $atoms . filter ( filter ) ;
if ( filter !== '*' ) {
if ( filter !== '*' ) {
$atomsToShow = $hiddenAtoms . filter ( filter ) ;
$atomsToShow = $hiddenAtoms . filter ( filter ) ;
var $atomsToHide = $visibleAtoms . not ( filter ) . toggleClass ( hiddenClass ) ;
var $atomsToHide = $visibleAtoms . not ( filter ) . toggleClass ( hiddenClass ) ;
$atomsToHide . addClass ( hiddenClass ) ;
$atomsToHide . addClass ( hiddenClass ) ;
prop s. styleQueue . push ( { $el : $atomsToHide , style : prop s. opts . hiddenStyle } ) ;
thi s. styleQueue . push ( { $el : $atomsToHide , style : thi s. option s . hiddenStyle } ) ;
}
}
prop s. styleQueue . push ( { $el : $atomsToShow , style : prop s. opts . visibleStyle } ) ;
thi s. styleQueue . push ( { $el : $atomsToShow , style : thi s. option s . visibleStyle } ) ;
$atomsToShow . removeClass ( hiddenClass ) ;
$atomsToShow . removeClass ( hiddenClass ) ;
}
}
return thi s;
return $filteredAtom s;
} ,
} ,
// ====================== Sorting ======================
// ====================== Sorting ======================
getSortFn : function ( sortBy , sortDir ) {
_ getSortFn : function ( sortBy , sortDir ) {
var getSorter = function ( elem ) {
var getSorter = function ( elem ) {
return $ ( elem ) . data ( 'molequul-sort-data' ) [ sortBy ] ;
return $ ( elem ) . data ( 'molequul-sort-data' ) [ sortBy ] ;
} ;
} ;
@ -261,12 +302,11 @@
} ,
} ,
// used on all the filtered atoms, $atoms.filtered
// used on all the filtered atoms, $atoms.filtered
sort : function ( props ) {
_ sort : function ( ) {
var sortFn = props . opts . sortBy === 'random' ? $ . molequul . randomSortFn :
var sortFn = this . _getSortFn ( this . options . sortBy , this . options . sortDir ) ;
$ . molequul . getSortFn ( props . opts . sortBy , props . opts . sortDir ) ;
prop s. atoms . $filtered . sort ( sortFn ) ;
thi s. atoms . $filtered . sort ( sortFn ) ;
return this ;
return this ;
} ,
} ,
@ -275,30 +315,29 @@
// ====================== Layout ======================
// ====================== Layout ======================
translate : function ( x , y ) {
_ translate : function ( x , y ) {
return { translate : [ x , y ] } ;
return { translate : [ x , y ] } ;
} ,
} ,
positionAbs : function ( x , y ) {
_ positionAbs : function ( x , y ) {
return { left : x , top : y } ;
return { left : x , top : y } ;
} ,
} ,
pushPosition : function ( x , y , props ) {
_pushPosition : function ( $elem , x , y ) {
var position = props . positionFn ( x , y ) ;
var position = this . positionFn ( x , y ) ;
props . styleQueue . push ( { $el : this , style : position } ) ;
this . styleQueue . push ( { $el : $elem , style : position } ) ;
return this ;
} ,
} ,
// ====================== masonry ======================
// ====================== masonry ======================
placeBrick : function ( setCount , setY , props ) {
_ placeBrick : function ( $brick , setCount , setY ) {
// here, `this` refers to a child element or "brick"
// here, `this` refers to a child element or "brick"
// get the minimum Y value from the columns
// get the minimum Y value from the columns
var minimumY = Math . min . apply ( Math , setY ) ,
var minimumY = Math . min . apply ( Math , setY ) ,
setHeight = minimumY + this . outerHeight ( true ) ,
setHeight = minimumY + $brick . outerHeight ( true ) ,
i = setY . length ,
i = setY . length ,
shortCol = i ,
shortCol = i ,
setSpan = prop s. colCount + 1 - i ,
setSpan = thi s. colCount + 1 - i ,
x , y ;
x , y ;
// Which column has the minY value, closest to the left
// Which column has the minY value, closest to the left
while ( i -- ) {
while ( i -- ) {
@ -308,16 +347,15 @@
}
}
// position the brick
// position the brick
x = prop s. colW * shortCol + prop s. posLeft ;
x = thi s. colW * shortCol + thi s. posLeft ;
y = minimumY ;
y = minimumY ;
this . molequul ( 'pushPosition' , x , y , props ) ;
this . _pushPosition ( $brick , x , y ) ;
// apply setHeight to necessary columns
// apply setHeight to necessary columns
for ( i = 0 ; i < setSpan ; i ++ ) {
for ( i = 0 ; i < setSpan ; i ++ ) {
prop s. colYs [ shortCol + i ] = setHeight ;
thi s. colYs [ shortCol + i ] = setHeight ;
}
}
return this ;
} ,
} ,
masonrySingleColumn : function ( props ) {
masonrySingleColumn : function ( props ) {
@ -327,32 +365,33 @@
} ,
} ,
masonryMultiColumn : function ( props ) {
_masonryMultiColumn : function ( $elems ) {
return this . each ( function ( ) {
var instance = this ;
$elems . each ( function ( ) {
var $this = $ ( this ) ,
var $this = $ ( this ) ,
//how many columns does this brick span
//how many columns does this brick span
colSpan = Math . ceil ( $this . outerWidth ( true ) / props . colW ) ;
colSpan = Math . ceil ( $this . outerWidth ( true ) / instance . colW ) ;
colSpan = Math . min ( colSpan , props . colCount ) ;
colSpan = Math . min ( colSpan , instance . colCount ) ;
if ( colSpan === 1 ) {
if ( colSpan === 1 ) {
// if brick spans only one column, just like singleMode
// if brick spans only one column, just like singleMode
$this . molequul ( 'placeBrick' , props . colCount , props . colYs , prop s ) ;
instance . _placeBrick ( $this , instance . colCount , instance . colYs ) ;
} else {
} else {
// brick spans more than one column
// brick spans more than one column
// how many different places could this brick fit horizontally
// how many different places could this brick fit horizontally
var groupCount = props . colCount + 1 - colSpan ,
var groupCount = instance . colCount + 1 - colSpan ,
groupY = [ ] ,
groupY = [ ] ,
groupColY ;
groupColY ;
// for each group potential horizontal position
// for each group potential horizontal position
for ( var i = 0 ; i < groupCount ; i ++ ) {
for ( var i = 0 ; i < groupCount ; i ++ ) {
// make an array of colY values for that one group
// make an array of colY values for that one group
groupColY = props . colYs . slice ( i , i + colSpan ) ;
groupColY = instance . colYs . slice ( i , i + colSpan ) ;
// and get the max value of the array
// and get the max value of the array
groupY [ i ] = Math . max . apply ( Math , groupColY ) ;
groupY [ i ] = Math . max . apply ( Math , groupColY ) ;
}
}
$this . molequul ( 'placeBrick' , groupCount , groupY , props ) ;
instance . _placeBrick ( $this , groupCount , groupY ) ;
}
}
} ) ;
} ) ;
} ,
} ,
@ -366,43 +405,37 @@
window . console && console . error ( 'Column width calculated to be zero. Stopping Molequul plugin before divide by zero. Check that the width of first child inside the molequul container is not zero.' ) ;
window . console && console . error ( 'Column width calculated to be zero. Stopping Molequul plugin before divide by zero. Check that the width of first child inside the molequul container is not zero.' ) ;
return this ;
return this ;
}
}
this . width = this . $elem . width ( ) ;
this . colCount = Math . floor ( this . width / this . colW ) ;
this . colCount = Math . floor ( this . width / this . colW ) ;
this . colCount = Math . max ( this . colCount , 1 ) ;
this . colCount = Math . max ( this . colCount , 1 ) ;
return this ;
return this ;
} ,
} ,
masonryResetLayoutProps : function ( props ) {
_masonryResetLayoutProps : function ( ) {
var i = this . colCount ;
var i = props . colCount ;
this . colYs = [ ] ;
props . colYs = [ ] ;
while ( i -- ) {
while ( i -- ) {
prop s. colYs . push ( prop s. posTop ) ;
thi s. colYs . push ( thi s. posTop ) ;
}
}
return this ;
return this ;
} ,
} ,
masonryResize : function ( props ) {
_ masonryResize : function ( ) {
var prevColCount = prop s. colCount ;
var prevColCount = thi s. colCount ;
// get updated colCount
// get updated colCount
this . molequul ( 'getMasonryColCount' , props ) ;
this . _getMasonryColCount ( ) ;
if ( prop s. colCount !== prevColCount ) {
if ( thi s. colCount !== prevColCount ) {
// if column count has changed, do a new column cound
// if column count has changed, do a new column cound
this . molequul ( 'reLayout' , props ) ;
this . reLayout ( ) ;
}
}
return this ;
return this ;
} ,
} ,
masonryMeasureContainerHeight : function ( props ) {
_masonryMeasureContainerHeight : function ( ) {
props . containerHeight = Math . max . apply ( Math , props . colYs ) - props . posTop ;
this . containerHeight = Math . max . apply ( Math , this . colYs ) - this . posTop ;
return this ;
} ,
_masonrySetup : function ( props ) {
this . molequul ( 'getMasonryColCount' , props ) ;
return this ;
} ,
} ,
@ -447,9 +480,8 @@
return this ;
return this ;
} ,
} ,
clearFloatMeasureContainerHeight : function ( props ) {
_clearFloatMeasureContainerHeight : function ( ) {
props . containerHeight = props . clearFloat . height ;
this . containerHeight = this . clearFloat . height ;
return this ;
} ,
} ,
clearFloatResize : function ( props ) {
clearFloatResize : function ( props ) {
@ -465,36 +497,37 @@
// accepts atoms-to-be-laid-out to start with
// accepts atoms-to-be-laid-out to start with
layout : function ( $elems , callback ) {
layout : function ( $elems , callback ) {
var props = this . data ( 'molequul' ) ,
var layoutMode = this . options . layoutMode ,
layoutMode = props . opts . layoutMode ,
layoutMethod = layoutMode ;
layoutMethod = layoutMode ;
// layout logic
// layout logic
if ( layoutMethod === 'masonry' ) {
if ( layoutMethod === 'masonry' ) {
layoutMethod = prop s. opts . masonrySingleMode ? 'masonrySingleColumn' : 'masonryMultiColumn' ;
layoutMethod = thi s. option s . masonrySingleMode ? '_ masonrySingleColumn' : '_ masonryMultiColumn' ;
}
}
$elems . molequul ( layoutMethod , props ) ;
this [ layoutMethod ] ( $elems ) ;
// $elems.molequul( layoutMethod, props );
// set the height of the container to the tallest column
// set the height of the container to the tallest column
this . molequul ( layoutMode + 'MeasureContainerHeight' , props ) ;
this [ '_' + layoutMode + 'MeasureContainerHeight' ] ( ) ;
var containerStyle = { height : prop s. containerHeight } ;
var containerStyle = { height : thi s. containerHeight } ;
prop s. styleQueue . push ( { $el : this , style : containerStyle } ) ;
thi s. styleQueue . push ( { $el : this . $elem , style : containerStyle } ) ;
// are we animating the layout arrangement?
// are we animating the layout arrangement?
// use plugin-ish syntax for css or animate
// use plugin-ish syntax for css or animate
var styleFn = ( prop s. applyStyleFnName === 'animate' && ! props . initialized ) ?
var styleFn = ( thi s. applyStyleFnName === 'animate' && ! $ . data ( this . $elem , 'molequul' ) ) ?
'css' : prop s. applyStyleFnName ,
'css' : thi s. applyStyleFnName ,
animOpts = prop s. opts . animationOptions ;
animOpts = thi s. option s . animationOptions ;
// process styleQueue
// process styleQueue
$ . each ( prop s. styleQueue , function ( i , obj ) {
$ . each ( thi s. styleQueue , function ( i , obj ) {
// have to extend animation to play nice with jQuery
// have to extend animation to play nice with jQuery
obj . $el [ styleFn ] ( obj . style , $ . extend ( { } , animOpts ) ) ;
obj . $el [ styleFn ] ( obj . style , $ . extend ( { } , animOpts ) ) ;
} ) ;
} ) ;
@ -502,7 +535,7 @@
// clear out queue for next time
// clear out queue for next time
prop s. styleQueue = [ ] ;
thi s. styleQueue = [ ] ;
// provide $elems as context for the callback
// provide $elems as context for the callback
if ( callback ) {
if ( callback ) {
@ -514,23 +547,19 @@
resize : function ( ) {
resize : function ( ) {
var props = this . data ( 'molequul' ) ;
return this [ '_' + this . options . layoutMode + 'Resize' ] ( ) ;
return this . molequul ( props . opts . layoutMode + 'Resize' , props ) ;
} ,
} ,
reLayout : function ( props ) {
reLayout : function ( callback ) {
props = props || this . data ( 'molequul' ) ;
console . log ( 'layout again' )
props . initialized = true ;
this
return this
[ '_' + this . options . layoutMode + 'ResetLayoutProps' ] ( )
. molequul ( props . opts . layoutMode + 'ResetLayoutProps' , props )
. layout ( this . atoms . $filtered , callback )
. molequul ( 'layout' , props . atoms . $filtered ) ;
} ,
} ,
// ====================== Setup and Init ======================
// ====================== Setup and Init ======================
watchedProps : [ 'filter' , 'sortBy' , 'sortDir' , 'layoutMode' ] ,
init : function ( options , callback ) {
init : function ( options , callback ) {