/*
*
* Project: WaltzerJS
* URL: http://www.waltzer-js.co.uk
* Author: Scott Carmichael
* Version: 1.0
*
* Copyright (c) 2013 Scott Carmichael
* Daul Licensed under GPL(http://www.gnu.org/licenses/gpl.html) & MIT (http://www.opensource.org/licenses/mit-license.php)
*
*/
;(function ($, window, document, undefined) {
$.fn.waltzer = function(config){
//Plugin Defaults
var defaults = {
developerMode: false,
vertical: false,
scroll: 1,
offset: 0,
circular: true,
auto: true,
autoPause : 2000,
speed: 1000,
easing: 'swing',
navBtns: true,
leftNavBtn: 'left-nav-btn',
rightNavBtn: 'right-nav-btn',
pager: false,
onCreate: null,
onComplete: null,
onForwardComplete: null,
onBackwardComplete: null
}
function plugin(container, config){
//Compile Plugin Options
this.options = $.extend({}, defaults, config);
//Gather Core Values
this.coreValues(container);
//Install Methods
this.utilities(this);
this.actions(this);
//Run Plugin
this.init(this);
};
plugin.prototype.coreValues = function(container){
this.$container = container;
this.$items = this.$container.children().not('.'+this.options.leftNavBtn+', .'+this.options.rightNavBtn);
//Create and Cache Navigation Buttons
if(this.options.navBtns){
$('
').appendTo(this.$container);
$('').appendTo(this.$container);
this.$buttons = this.$container.find( '.'+this.options.leftNavBtn+', .'+this.options.rightNavBtn );
}
this.itemCount = this.$items.length;
if(this.options.vertical){
this.containerWidth = this.$container.outerHeight(false);
this.itemWidth = this.$items.outerHeight(true);
this.itemMarginWidth = this.itemWidth - this.$items.outerHeight(false);
this.containerHeight = this.containerWidth;
} else {
this.containerWidth = this.$container.outerWidth(false);
this.itemWidth = this.$items.outerWidth(true);
this.itemMarginWidth = this.itemWidth - this.$items.outerWidth(false);
this.containerHeight = this.$items.outerHeight(false);
}
this.innerWrapperWidth = (this.itemWidth * this.itemCount);
this.innerWrapperPos = 0;
this.speed = this.options.scroll * this.options.speed;
this.scrollWidth = this.itemWidth*this.options.scroll;
this.pageCount = 1;
//Turn Circular Off For Pager Display
this.options.circular = this.options.pager ? false : this.options.circular;
//Test Scroll and Reset Value if Unsuitable
if(this.itemCount % this.options.scroll != 0 || ((this.containerWidth / this.itemWidth)+1) < this.options.scroll){
for(i=this.options.scroll-1;i>=1;i--){
if(this.itemCount % i == 0 && ((this.containerWidth / this.itemWidth)+1) > i){
this.options.scroll = i;
break;
}
}
}
}
plugin.prototype.utilities = function(self){
//Reorder List Items
this.cutAndPaste = function(direction){
if(direction == 'forward'){
for(i=0;i=this.itemCount-this.options.scroll;i--){
this.innerWrapper.prepend(this.$items[i]);
}
}
}
//Refresh List Order After Item Move
this.refreshItemList = function(){
return this.$items = this.innerWrapper.children('div.item');
}
//Page Count
this.updatePageCount = function(direction, amount){
amount = amount == undefined || amount == false ? 1 : amount;
for(i=0; i 1){
this.pageCount--;
} else {
this.pageCount = this.itemCount / this.options.scroll;
}
}
}
//Update Pager Active State
if(this.options.pager){
this.$container.find('.pager').children('span').removeClass('active');
this.$container.find('.pager').children('span[data-button ='+this.pageCount+']').addClass('active');
}
}
//Activate Auto Scrolling
this.addAuto = function(){
if( this.options.auto ){
return setInterval(function(){
self.move('forward');
}, this.options.autoPause );
}
return false;
}
this.removeAuto = function(){
return this.options.auto ? clearInterval(self.autoScroll) : false;
}
//Trigger Multiple Events
this.eventTrigger = function(events){
if( typeof events == 'string' ){
self.$container.trigger(events);
} else {
for(i=0; i < events.length; i++){
self.$container.trigger(events[i]);
}
}
}
this.animateFunction = function(position, direction, amount){
this.innerWrapper.animate(position, this.speed, this.easing, function(){
self.updatePageCount(direction, amount);
self.directionCallBack.resolve(direction);
self.completeCallBack.resolve('completed');
//Completion Events
self.eventTrigger([direction+'Complete', 'moved']);
});
}
}
plugin.prototype.actions = function(self){
this.animate = function(direction, amount){
//Return if Animation in Progress
if(this.innerWrapper.is(':animated')){
return false;
}
var posObject = {},
offset = this.options.vertical == true ? 'top' : 'left',
amount = amount == undefined || amount == false ? 1 : amount,
scrollDistance = this.scrollWidth * amount;
//Refresh Deferreds
this.directionCallBack = $.Deferred();
this.completeCallBack = $.Deferred();
//Set Scroll Width
posObject[offset] = direction == 'forward' ? '-='+scrollDistance : '+='+scrollDistance;
//Fire Forward Event
this.eventTrigger(direction);
if(direction == 'forward'){
if((this.innerWrapperWidth + this.innerWrapperPos[offset]) > this.containerWidth+this.itemWidth){
//Animate InnerWrapper
this.animateFunction(posObject, direction, amount);
} else if(this.options.circular){
//Cut and Move Item
this.cutAndPaste('forward');
//Reset InnerWrapper Position
this.innerWrapper.css(offset, this.innerWrapperPos[offset]+this.scrollWidth);
//Animate InnerWrapper
this.animateFunction(posObject, direction, amount);
//Refresh Item List Order
this.refreshItemList();
} else if(!this.options.circular) {
posObject[offset] = 0;
//Animate InnerWrapper
this.animateFunction(posObject, direction, amount);
}
} else if(direction == 'backward'){
if(this.innerWrapperPos[offset] < 0){
//Animate InnerWrapper
this.animateFunction(posObject, direction, amount);
} else if(this.options.circular){
//Cut and Move Item
this.cutAndPaste('backward');
//Reset InnerWrapper Position
this.innerWrapper.css(offset, this.innerWrapperPos[offset]-this.scrollWidth);
//Animate InnerWrapper
this.animateFunction(posObject, direction, amount);
//Refresh Item List Order
this.refreshItemList();
} else if(!this.options.circular) {
if(this.scrollWidth < this.containerWidth){
var marginWidth = this.containerWidth;
while(marginWidth>0){
marginWidth -= this.itemWidth;
}
posObject[offset] = (this.innerWrapperWidth - this.containerWidth+marginWidth)*-1;
} else {
posObject[offset] = (this.innerWrapperWidth - this.scrollWidth)*-1
}
//Animate InnerWrapper
this.animateFunction(posObject, direction, amount);
}
}
//Initialize Callbacks
this.initCallBacks(this.directionCallBack, this.completeCallBack);
},
this.initCallBacks = function(direction, complete){
//Forward/Backward Completion Callback
if(self.options.onForwardComplete || self.options.onBackwardComplete){
direction.done(function(data){
if(data == 'forward'){
if(typeof self.options.onForwardComplete == 'function'){
self.options.onForwardComplete.call(self);
}
} else if(data == 'backward'){
//backward Complete Callback
if(typeof self.options.onBackwardComplete == 'function'){
self.options.onBackwardComplete.call(self);
}
}
});
}
//Completion Callback
if(typeof self.options.onComplete == 'function'){
complete.done(function(data){
self.options.onComplete.call(self);
});
}
}
}
plugin.prototype.init = function(self){
//Wrap items in Container
if(this.options.vertical){
this.$items.wrapAll('');
} else {
this.$items.wrapAll('');
}
//Capture InnerWrapper
this.innerWrapper = this.$container.children('div.innerWrapper');
//Create Mask
this.innerWrapper.wrap('');
//Offset Alter Array
if(this.options.offset != 0){
for(i=0;i