(function (factory){
if(typeof define==='function'&&define.amd){
define(['jquery'], factory);
}else if(typeof module==='object'&&module.exports){
module.exports=function(root, jQuery){
if(jQuery===undefined){
if(typeof window!=='undefined'){
jQuery=require('jquery');
}else{
jQuery=require('jquery')(root);
}}
factory(jQuery);
return jQuery;
};}else{
factory(jQuery);
}}(function ($){
var cloneWithCanvases=function(jqueryObject){
var clonedJqueryObject=jqueryObject.clone(true, true);
var canvases=jqueryObject.find('canvas');
if(canvases.length){
var clonedCanvases=clonedJqueryObject.find('canvas');
clonedCanvases.each(function(index){
var context=this.getContext('2d');
context.drawImage(canvases.get(index), 0, 0);
});
}
return clonedJqueryObject;
};
$.fn.quicksand=function(collection, customOptions){
var options={
duration:750,
easing:'swing',
attribute:'data-id',
adjustHeight:'call',        // 'dynamic' animates height during shuffling (slow), 'call' adjusts it
adjustWidth:false,          // 'dynamic' animates width during shuffling (slow),
useScaling:false,
enhancement:function(c){},
selector:'> *',
atomic:false,
dx:0,
dy:0,
maxWidth:0,
retainExisting:true
};
$.extend(options, customOptions);
if((typeof ($.transform)=='undefined')){
options.useScaling=false;
}
var callbackFunction;
if(typeof (arguments[1])=='function'){
callbackFunction=arguments[1];
}else if(typeof (arguments[2]=='function')){
callbackFunction=arguments[2];
}
var that=this;
return this.each(function(i){
var val;
var animationQueue=[];
var $collection;
if(typeof(options.attribute)=='function'){
$collection=$(collection);
}else{
$collection=cloneWithCanvases($(collection).filter('[' + options.attribute + ']'));
}
var $sourceParent=$(this);
var sourceHeight=$(this).css('height');
var sourceWidth=$(this).css('width');
var destHeight, destWidth;
var adjustHeightOnCallback=false;
var adjustWidthOnCallback=false;
var offset=$($sourceParent).offset();
var offsets=[];
var $source=$(this).find(options.selector);
var width=$($source).innerWidth();
if(navigator.userAgent.match(/msie [6]/i)){
$sourceParent.html('').append($collection);
return;
}
var postCallbackPerformed=0;
var postCallback=function(){
$(this).css('margin', '').css('position', '').css('top', '').css('left', '').css('opacity', '');
if(!postCallbackPerformed){
postCallbackPerformed=1;
if(!options.atomic){
var $toDelete=$sourceParent.find(options.selector);
if(!options.retainExisting){
$sourceParent.prepend($dest.find(options.selector));
$toDelete.remove();
}else{
var $keepElements=$([]);
$dest.find(options.selector).each(function(i){
var $matchedElement=$([]);
if(typeof (options.attribute)=='function'){
var val=options.attribute($(this));
$toDelete.each(function(){
if(options.attribute(this)==val){
$matchedElement=$(this);
return false;
}});
}else{
$matchedElement=$toDelete.filter('[' + options.attribute + '="'+
$(this).attr(options.attribute) + '"]');
}
if($matchedElement.length > 0){
$keepElements=$keepElements.add($matchedElement);
if(i===0){
$sourceParent.prepend($matchedElement);
}else{
$matchedElement.insertAfter($sourceParent.find(options.selector).get(i - 1));
}}
});
$toDelete.not($keepElements).remove();
}
if(adjustHeightOnCallback){
$sourceParent.css('height', destHeight);
}
if(adjustWidthOnCallback){
$sourceParent.css('width', sourceWidth);
}}
options.enhancement($sourceParent);
if(typeof callbackFunction=='function'){
callbackFunction.call(that);
}}
if('auto'===options.adjustHeight){
$sourceParent.css('height', 'auto');
}
if('auto'===options.adjustWidth){
$sourceParent.css('width', 'auto');
}};
var $correctionParent=$sourceParent.offsetParent();
var correctionOffset=$correctionParent.offset();
if($correctionParent.css('position')=='relative'){
if($correctionParent.get(0).nodeName.toLowerCase()!='body'){
correctionOffset.top +=(parseFloat($correctionParent.css('border-top-width'))||0);
correctionOffset.left +=(parseFloat($correctionParent.css('border-left-width'))||0);
}}else{
correctionOffset.top -=(parseFloat($correctionParent.css('border-top-width'))||0);
correctionOffset.left -=(parseFloat($correctionParent.css('border-left-width'))||0);
correctionOffset.top -=(parseFloat($correctionParent.css('margin-top'))||0);
correctionOffset.left -=(parseFloat($correctionParent.css('margin-left'))||0);
}
if(isNaN(correctionOffset.left)){
correctionOffset.left=0;
}
if(isNaN(correctionOffset.top)){
correctionOffset.top=0;
}
correctionOffset.left -=options.dx;
correctionOffset.top -=options.dy;
if(options.adjustHeight!==false){
$sourceParent.css('height', $(this).height());
}
if(options.adjustWidth!==false){
$sourceParent.css('width', $(this).width());
}
$source.each(function(i){
offsets[i]=$(this).offset();
});
$(this).stop();
var dx=0;
var dy=0;
$source.each(function(i){
$(this).stop();
var rawObj=$(this).get(0);
if(rawObj.style.position=='absolute'){
dx=-options.dx;
dy=-options.dy;
}else{
dx=options.dx;
dy=options.dy;
}
rawObj.style.position='absolute';
rawObj.style.margin='0';
if(!options.adjustWidth){
rawObj.style.width=(width + 'px');
}
rawObj.style.top=(offsets[i].top- parseFloat(rawObj.style.marginTop) - correctionOffset.top + dy) + 'px';
rawObj.style.left=(offsets[i].left- parseFloat(rawObj.style.marginLeft) - correctionOffset.left + dx) + 'px';
if(options.maxWidth > 0&&offsets[i].left > options.maxWidth){
rawObj.style.display='none';
}});
var $dest=cloneWithCanvases($($sourceParent));
var rawDest=$dest.get(0);
rawDest.innerHTML='';
rawDest.setAttribute('id', '');
rawDest.style.height='auto';
rawDest.style.width=$sourceParent.width() + 'px';
$dest.append($collection);
$dest.insertBefore($sourceParent);
$dest.css('opacity', 0.0);
rawDest.style.zIndex=-1;
rawDest.style.margin='0';
rawDest.style.position='absolute';
rawDest.style.top=offset.top - correctionOffset.top + 'px';
rawDest.style.left=offset.left - correctionOffset.left + 'px';
if(options.adjustHeight==='dynamic'){
$sourceParent.animate({ height:$dest.height() }, options.duration, options.easing);
}else if(options.adjustHeight==='call'){
destHeight=$dest.height();
if(parseFloat(sourceHeight) < parseFloat(destHeight)){
$sourceParent.css('height', destHeight);
}else{
adjustHeightOnCallback=true;
}}
if(options.adjustWidth==='dynamic'){
$sourceParent.animate({ width:$dest.width() }, options.duration, options.easing);
}else if(options.adjustWidth==='call'){
destWidth=$dest.width();
if(parseFloat(sourceWidth) < parseFloat(destWidth)){
$sourceParent.css('width', destWidth);
}else{
adjustWidthOnCallback=true;
}}
$source.each(function(i){
var destElement=[];
if(typeof (options.attribute)=='function'){
val=options.attribute($(this));
$collection.each(function(){
if(options.attribute(this)==val){
destElement=$(this);
return false;
}});
}else{
destElement=$collection.filter('[' + options.attribute + '="' + $(this).attr(options.attribute) + '"]');
}
if(destElement.length){
if(!options.useScaling){
animationQueue.push({
element:$(this), dest:destElement,
style:{
top:$(this).offset().top,
left:$(this).offset().left,
opacity:""
},
animation:{
top:destElement.offset().top - correctionOffset.top,
left:destElement.offset().left - correctionOffset.left,
opacity:1.0
}});
}else{
animationQueue.push({
element:$(this), dest:destElement,
style:{
top:$(this).offset().top,
left:$(this).offset().left,
opacity:""
},
animation:{
top:destElement.offset().top - correctionOffset.top,
left:destElement.offset().left - correctionOffset.left,
opacity:1.0,
transform:'scale(1.0)'
}});
}}else{
if(!options.useScaling){
animationQueue.push({
element:$(this),
style:{
top:$(this).offset().top,
left:$(this).offset().left,
opacity:""
},
animation:{
opacity:'0.0'
}});
}else{
animationQueue.push({
element:$(this),
style:{
top:$(this).offset().top,
left:$(this).offset().left,
opacity:""
},
animation:{
opacity:'0.0',
transform:'scale(0.0)'
}});
}}
});
$collection.each(function(i){
var sourceElement=[];
var destElement=[];
if(typeof (options.attribute)=='function'){
val=options.attribute($(this));
$source.each(function(){
if(options.attribute(this)==val){
sourceElement=$(this);
return false;
}});
$collection.each(function(){
if(options.attribute(this)==val){
destElement=$(this);
return false;
}});
}else{
sourceElement=$source.filter('[' + options.attribute + '="' + $(this).attr(options.attribute) + '"]');
destElement=$collection.filter('[' + options.attribute + '="' + $(this).attr(options.attribute) + '"]');
}
var animationOptions;
if(sourceElement.length===0&&destElement.length > 0){
if(!options.useScaling){
animationOptions={opacity:'1.0'};}else{
animationOptions={opacity:'1.0', transform:'scale(1.0)'};}
var d=cloneWithCanvases(destElement);
var rawDestElement=d.get(0);
rawDestElement.style.position='absolute';
rawDestElement.style.margin='0';
if(!options.adjustWidth){
rawDestElement.style.width=width + 'px';
}
rawDestElement.style.top=destElement.offset().top - correctionOffset.top + 'px';
rawDestElement.style.left=destElement.offset().left - correctionOffset.left + 'px';
d.css('opacity', 0.0);
if(options.useScaling){
d.css("transform", "scale(0.0)");
}
d.appendTo($sourceParent);
if(options.maxWidth===0||destElement.offset().left < options.maxWidth){
animationQueue.push({element:$(d), dest:destElement,animation:animationOptions});
}}
});
$dest.remove();
if(!options.atomic){
options.enhancement($sourceParent);
for (i=0; i < animationQueue.length; i++){
animationQueue[i].element.animate(animationQueue[i].animation, options.duration, options.easing, postCallback);
}}else{
$toDelete=$sourceParent.find(options.selector);
$sourceParent.prepend($dest.find(options.selector));
for (i=0; i < animationQueue.length; i++){
if(animationQueue[i].dest&&animationQueue[i].style){
var destElement=animationQueue[i].dest;
var destOffset=destElement.offset();
destElement.css({
position:'relative',
top:(animationQueue[i].style.top - destOffset.top),
left:(animationQueue[i].style.left - destOffset.left)
});
destElement.animate({top:"0", left:"0"},
options.duration,
options.easing,
postCallback);
}else{
animationQueue[i].element.animate(animationQueue[i].animation,
options.duration,
options.easing,
postCallback);
}}
$toDelete.remove();
}});
};}));