Last active
August 29, 2015 14:06
-
-
Save tommycoppers/6b4929d9710bd95ebc0d to your computer and use it in GitHub Desktop.
Touch ready carousel/slider
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;(function($, window, document, undefined){ | |
$.fn.carousel = function(options) { | |
return this.each(function() { | |
if (!$(this).data('carousel')) { | |
$(this).data('carousel', new Carousel(this, options)); | |
} | |
}); | |
}; | |
function Carousel(element, options) { | |
var $carousel = $(element); | |
////////// === Triggers === ////////// | |
/** | |
* Event triggers include: | |
* | |
* ___ Init ___ | |
* $carousel.on('carousel.ready') - Callback after plugin has been initialized | |
* | |
* ___ Moving ___ | |
* $carousel.on('carousel.move-stage.start') - Start of the stage moving | |
* $carousel.on('carousel.move-stage.complete') - Callback after completion of stage move | |
* | |
* ___ Views ___ | |
* $carousel.on('carousel.update-to-mobile.start') - Start transitioning to Mobile view | |
* $carousel.on('carousel.update-to-mobile.complete') - Callback after transitioning to Mobile view | |
* | |
* ___ Autoplay ___ | |
* $carousel.on('carousel.autoplay.start') - Starting Autoplay | |
* $carousel.on('carousel.autoplay.pause') - Pausing Autoplay | |
* | |
* ___ Drag ___ | |
* $carousel.on('carousel.drag.start') - Starting drag | |
* $carousel.on('carousel.drag.end') - Ending drag | |
* | |
*/ | |
////////// === Handle Errors Before they Begin === ////////// | |
if (!$carousel.length || !$carousel.children().length ) { | |
return false; | |
} | |
////////// === Set Defaults -> Settings === ////////// | |
var defaults = { | |
// Nav | |
showNav : true, // (bool) - Displays Navigation | |
// Display | |
generateHTML : true, // (bool) - Auto Generate the HTML structure or take full control over it | |
updateItemsParent : false, // (string) - Selector of parent to the carousel items. Otherwise, parent is $carousel ** Only applicable when generateHTML is set to true | |
forceItemNum : false, // (num) - Force Item Number | |
forceItemNumMap : false, // (object) - Force Item Number Map. | |
moveBy : 1, // (num) - Slide by number of items | |
mobile : 550, // (num) - Min window width (px) before entering a single column (turn off mobile with false or forceItemNum) | |
imageDriven : false, // (bool) - Limits the carousel item's width to width of the image by adding a max-width css property | |
// Dragging | |
mouseDrag : false, // (bool) - Allow mouse dragging to move carousel | |
touchDrag : true, // (bool) - Allow touch dragging to move carousel | |
// Auto Plays | |
autoplay : true, // (bool) - Auto move the carousel | |
autoplaySpeed : 8000, // (num) - Time (in ms) to pause on each item | |
autoplayTimeout : 2000, // (num) - Time (in ms) to initialize the autoplay | |
autoplayHoverPause : true, // (bool) - Enable/disable pause on hover | |
loop : true, | |
// Naming | |
viewportClass : 'carousel__viewport', | |
stageClass : 'carousel__stage', | |
navClass : 'carousel__nav', | |
prevBtnClass : 'carousel__prev-btn', | |
nextBtnClass : 'carousel__next-btn', | |
itemsClass : 'carousel__item', | |
activeClass : 'carousel__item--active', | |
nextToActiveClass : 'carousel__item--next-active', | |
prevToActiveClass : 'carousel__item--prev-active', | |
loadedClass : 'carousel--loaded', | |
pauseAnimationClass : 'carousel--pause-animation', | |
mobileViewClass : 'carousel--mobile-view', | |
touchClass : 'carousel--touch' | |
}; | |
var settings = $.extend({}, defaults, options); | |
////////// === Set Initial Variables and Constants === ////////// | |
var $window = $(window), | |
$document = $(document), | |
$html = $('html'), | |
dragEvents = '', | |
// ___ initial states ___ | |
carouselReadyQueue = { | |
added : [], | |
removed : [] | |
}, | |
carouselReady, | |
stage = { | |
offset : 0, | |
margin : 0 | |
}, | |
drag = { | |
start : {}, | |
distance : {}, | |
target : false | |
}, | |
forceItemNum = { | |
timeout : false, | |
width : false, | |
num : false | |
}, | |
autoplay = { | |
timeout : false, | |
paused : false, | |
initialized : false | |
}, | |
items = { | |
$original : false, | |
$current : false, | |
$active : false, | |
$nextActive : false, | |
$nextToActive : false, | |
$prevToActive : false | |
}, | |
$stage, | |
$viewport, | |
$nav, | |
$nextBtn, | |
$prevBtn, | |
mobileViewActive; | |
////////// === Scripts === ////////// | |
// ___ Support ___ | |
function isTouchSupport() { | |
return 'ontouchstart' in window && !(window.navigator.msPointerEnabled); | |
} | |
function isTouchSupportIE() { | |
return window.navigator.msPointerEnabled; | |
} | |
// ___ Drag ___ | |
function getEventObject (event) { | |
return event.originalEvent || event || window.event; | |
} | |
function getTouches(event) { | |
/** | |
* Returns placement on the page where the touch or mouse event occurred | |
* @param {String} event - The event name. | |
*/ | |
// Check if touch device | |
if (event.touches !== undefined) { | |
return { | |
x: event.touches[0].pageX, | |
y: event.touches[0].pageY | |
}; | |
} | |
// Check if non-touch device | |
if (event.touches === undefined) { | |
// Cool browsers | |
if (event.pageX !== undefined) { | |
return { | |
x: event.pageX, | |
y: event.pageY | |
}; | |
} | |
// IE :( | |
if (event.pageX === undefined) { | |
return { | |
x: event.clientX, | |
y: event.clientY | |
}; | |
} | |
} | |
} | |
function onDragStart (event) { | |
$carousel.trigger('carousel.drag.start'); | |
var ev = getEventObject(event); | |
drag.target = ev.target; | |
drag.start.x = getTouches(ev).x; | |
drag.start.y = getTouches(ev).y; | |
// Assume that if user drags, they want animation to pause indefinitely | |
$carousel.addClass(settings.pauseAnimationClass); | |
pauseAutoplay(); | |
updateCurrentItems(); // comment about why this is done (pre-cache so it doesnt have to recalculate on drag move) | |
// Bind other touch events | |
$document.on( dragEvents , $.proxy(function(ev) {touchEventRouter(ev);}, this)); | |
} | |
function onDragMove (event) { | |
var ev = getEventObject(event), | |
tempMove = stage.offset + drag.distance.x; | |
drag.distance.x = getTouches(ev).x - drag.start.x; | |
updateStagePosition(tempMove); | |
} | |
function onDragEnd () { | |
var dragThreshold = 20; | |
// Suppress a click if the event target was an anchor tag and the drag was intentional | |
if (drag.target && $(drag.target).length && Math.abs(drag.distance.x) > 5) { | |
suppressClick(drag.target); | |
} | |
// Finalize the stage position | |
if (drag.distance.x < -(dragThreshold)) { | |
moveNext(); | |
} else if (drag.distance.x > dragThreshold ) { | |
movePrev(); | |
} else if (Math.abs(drag.distance.x) > 0) { | |
updateStagePosition(stage.offset); | |
} | |
// Finish up! Reset, Unbind and trigger | |
resetDragProps(); | |
$carousel.removeClass(settings.pauseAnimationClass); | |
$document.off( dragEvents ); | |
$carousel.trigger('carousel.drag.end'); | |
} | |
function resetDragProps () { | |
drag.start.x = 0; | |
drag.distance.x = 0; | |
drag.target = false; | |
} | |
// ___ Internal Events ___ | |
function touchEventRouter (event) { | |
var type = event.type; | |
if (type === "mousedown" || type === "touchstart" || type === "pointerdown") { | |
onDragStart(event); | |
} else if (type === "mousemove" || type === "touchmove" || type === "pointermove") { | |
onDragMove(event); | |
} else if (type === "mouseup" || type === "touchend" || type === "pointerup") { | |
onDragEnd(); | |
} else if (type === "touchcancel") { | |
onDragEnd(); | |
} | |
} | |
function initEvents () { | |
// ___ Next Button ___ | |
if ($nextBtn) { | |
$nextBtn.on('click.next', function (e) { | |
e.preventDefault(); | |
moveNext(); | |
}); | |
} | |
// ___ Previous Button ___ | |
if ($prevBtn) { | |
$prevBtn.on('click.prev', function (e) { | |
e.preventDefault(); | |
movePrev(); | |
}); | |
} | |
// ___ Window Resizing ___ | |
$window.on('resize', function () { | |
if (settings.forceItemNum) { | |
clearTimeout(forceItemNum.timeout); | |
forceItemNum.timeout = setTimeout(function(){ | |
forceItemNumRouter(); | |
}, 200); | |
} | |
}); | |
// ___ Mouse Dragging ___ | |
if (settings.mouseDrag && !isTouchSupport()){ | |
$stage.on('mousedown', $.proxy(function(event) { | |
touchEventRouter(event); | |
}, this)); | |
$stage.on('dragstart', function() { return false; }); | |
$stage.get(0).onselectstart = function() { return false; }; // WTF MATE? | |
} | |
// ___ Touch Dragging ___ | |
if (settings.touchDrag && isTouchSupport()){ | |
dragEvents = 'mousemove.carousel mouseup.carousel touchmove.carousel touchend.carousel'; | |
$carousel.addClass(settings.touchClass); | |
$stage.on('touchstart', $.proxy(function(event) { touchEventRouter(event); }, this)); | |
} | |
if (settings.touchDrag && isTouchSupportIE()){ | |
dragEvents = 'pointermove.carousel pointerup.carousel'; | |
$carousel.addClass(settings.touchClass); | |
$stage.css({'-ms-touch-action':'none'}).on('pointerdown', $.proxy(function(event) { touchEventRouter(event); }, this)); | |
} | |
} | |
function loadImage (images, callback) { | |
var $images = $(images); | |
var imagesProcessed = 0; | |
var imagesLen = $images.length; | |
function isAllImages () { | |
if (imagesProcessed === imagesLen) { | |
callback && callback(); | |
} | |
} | |
function processImage () { | |
imagesProcessed += 1; | |
isAllImages(); | |
} | |
$images.each(function () { | |
var $img = $(this); | |
var src = $img.attr('src') + '?'+ new Date().getTime(); | |
$img.attr('src', src ); | |
$img | |
.on('load', processImage) | |
.on('error', function () { | |
$(this).remove(); | |
processImage(); | |
}); | |
}); | |
} | |
function suppressClick (target) { | |
$(target).on('click.preventTouchClick', function (e) { | |
if (e.preventDefault) { | |
e.preventDefault(); | |
} | |
if (e.stopPropagation) { | |
e.stopPropagation(); | |
} | |
$(this).off('click.preventTouchClick'); | |
}); | |
} | |
// ___ Initializing ___ | |
function preInitialize() { | |
$window.on('load', function () { | |
loadImage ($carousel.find('img'), initialize); | |
}); | |
} | |
function initialize () { | |
if (settings.generateHTML) { | |
generateHTML(); | |
} | |
if (settings.showNav) { | |
generateNav(); | |
} | |
setElements(); | |
setItemData(); | |
if (settings.forceItemNum) { | |
forceItemNumRouter(); | |
} | |
if (settings.imageDriven) { | |
setImageDrivenWidth(); | |
} | |
if (settings.loop) { | |
addToReadyQueue('loop'); | |
initLoop(); | |
} | |
if (settings.mobile && !settings.forceItemNum) { | |
if ($window.width() <= settings.mobile) { | |
addToReadyQueue('mobile'); | |
updateToMobileView(); | |
} | |
$window.on('resize', function () { // throttle this? | |
var width = $window.width(); | |
if (!mobileViewActive && width <= settings.mobile) { | |
updateToMobileView(); | |
} | |
else if (mobileViewActive && width > settings.mobile) { | |
escapeMobileView(); | |
} | |
}); | |
} | |
if (settings.autoplay) { | |
setTimeout(function () { | |
autoplay.initialized = true; | |
startAutoplay(); | |
}, settings.autoplayTimeout); | |
if (settings.autoplayHoverPause) { | |
$nav.add($stage) | |
.on('mouseenter',function () { | |
pauseAutoplay(); | |
}) | |
.on('mouseleave',function () { | |
resumeAutoplay(); | |
}); | |
} | |
} | |
initEvents(); | |
readyCheck(); | |
} | |
function setElements () { | |
items.$original = $carousel.find('.' + settings.itemsClass); | |
items.$current = items.$original; | |
$stage = $carousel.find('.' + settings.stageClass); | |
$viewport = $carousel.find('.' + settings.viewportClass); | |
} | |
function setItemData () { | |
var itemPositionCount = 1; | |
items.$current.each(function () { | |
$(this).data('item-position', itemPositionCount); | |
itemPositionCount +=1; | |
}); | |
items.$current.first().addClass(settings.activeClass).next().addClass(settings.nextToActiveClass); | |
items.$current.prev().addClass(settings.prevToActiveClass); | |
} | |
function generateNav () { | |
$carousel.append( | |
'<div class="'+ settings.navClass +'">' + | |
'<span class="' + settings.prevBtnClass + '"></span><span class="' + settings.nextBtnClass + '"></span>' + | |
'</div>'); | |
$nav = $carousel.find('.' + settings.navClass); | |
$nextBtn = $nav.find('.' + settings.nextBtnClass); | |
$prevBtn = $nav.find('.' + settings.prevBtnClass); | |
} | |
function initLoop () { | |
// Shorter lists will determine if we need to copy over all the times to simulate a loop or just a few | |
var shortList = items.$original.length < 6; | |
// If not a short list, split the original in half so that we can get a full loop | |
var numToAppend = Math.ceil(items.$original.length/2); | |
var numToPrepend = items.$original.length - numToAppend; | |
// Create clones to put on both sides of the original items | |
var $clonesToPrepend = (shortList) ? items.$original.clone() : items.$original.last().prevAll(':lt('+(numToPrepend -1)+')').andSelf().clone(); | |
var $clonesToAppend = (shortList) ? items.$original.clone() : items.$original.first().nextAll(':lt('+(numToAppend -1)+')').andSelf().clone(); | |
// Remove any classes related to active classes, add a cloned class | |
$clonesToAppend | |
.add($clonesToPrepend) | |
.addClass('cloned') | |
.removeClass(settings.activeClass) | |
.removeClass(settings.nextToActiveClass) | |
.removeClass(settings.prevToActiveClass); | |
$stage.prepend($clonesToPrepend).append($clonesToAppend); | |
// Determine how far to shift the stage and shift | |
var offset = getCollectionWidth($clonesToPrepend); | |
moveStage(offset, false, function(){ | |
removeFromReadyQueue('loop'); | |
}); | |
// Update the items list to include the clones | |
updateCurrentItems(); | |
updateStageWidth(); | |
} | |
function addToReadyQueue (process) { | |
/** | |
* Alerts that a partial feature needs to be initialized before the carousel is ready to display | |
* - Depends on carouselReadyQueue | |
*/ | |
// carouselReadyQueue.added.push(process); | |
} | |
function removeFromReadyQueue (process) { | |
/** | |
* Callback for when a partial feature is initialized then removes itself from the carouselReadyQueue | |
* - Depends on carouselReadyQueue | |
*/ | |
// if (!carouselReady) { | |
// carouselReadyQueue.removed.push(process); | |
// readyCheck(); | |
// } | |
} | |
function readyCheck () { | |
/** | |
* Checks if the module is configured and ready to display. | |
* When ready, a loadedClass is added and carousel.ready is triggered | |
* - Depends on carouselReadyQueue | |
*/ | |
if (carouselReadyQueue.added.length === carouselReadyQueue.removed.length) { | |
carouselReady = true; | |
$carousel.addClass(settings.loadedClass).data('is-loaded',true).trigger('carousel.ready'); | |
} | |
} | |
function generateHTML () { | |
/** | |
* Generates HTML framework for carousel | |
*/ | |
var $itemsParent = (settings.updateItemsParent) ? $carousel.find(settings.updateItemsParent) : $carousel ; | |
var $itemsToWrap = $itemsParent.children(); | |
$itemsToWrap.removeClass(settings.itemsClass); | |
$itemsParent.wrapInner('<ul class="' + settings.stageClass + '"/>'); | |
$carousel.wrapInner('<div class="' + settings.viewportClass + '"/>'); | |
$itemsToWrap.wrap('<li class="' + settings.itemsClass + '"/>'); | |
} | |
function setImageDrivenWidth (removeStyles) { | |
items.$current.each(function(){ | |
var $this = $(this); | |
var $img = $($this.find('img')[0]); | |
var imgWidth = $img.width(); | |
if ($img.length && imgWidth > 0 && ($img.context.naturalWidth !== undefined && $img.context.naturalWidth > 0)) { | |
if (!removeStyles) { | |
$this.css({ 'max-width': imgWidth }); | |
} | |
else { | |
$this.css({ 'max-width': '' }); | |
} | |
} | |
else { | |
$this.addClass( settings.itemsClass + '--no-image' ); | |
} | |
}); | |
} | |
// ___ Fit Items ___ | |
function forceItemNumRouter () { | |
if (typeof settings.forceItemNum === 'number' && !settings.forceItemNumMap) { | |
resizeItem (settings.forceItemNum); | |
} | |
else if (settings.forceItemNumMap && typeof settings.forceItemNumMap === 'object') { | |
forceItemNumMap(); | |
} | |
} | |
function forceItemNumMap () { | |
var useDefault = true; | |
var width = $window.width(); | |
for (var breakpointWidth in settings.forceItemNumMap) { | |
if (settings.forceItemNumMap.hasOwnProperty(breakpointWidth)) { | |
var val = settings.forceItemNumMap[breakpointWidth]; | |
if (width < breakpointWidth) { | |
resizeItem(val); | |
settings.moveBy = val; | |
useDefault = false; | |
return; | |
} | |
} | |
} | |
if (useDefault) { | |
settings.moveBy = settings.forceItemNum; | |
resizeItem(settings.forceItemNum); | |
} | |
} | |
function resizeItem (itemNum) { | |
var newItemWidth = $viewport.width() / itemNum; | |
if (forceItemNum.width !== newItemWidth) { | |
forceItemNum.width = newItemWidth; | |
resetPosition(); | |
} | |
} | |
// ___ Updating Data/Views ___ | |
function updateCurrentItems () { | |
// Update Items | |
items.$current = $carousel.find('.' + settings.itemsClass); | |
items.$active = items.$current.filter('.' + settings.activeClass); | |
items.$nextToActive = items.$current.filter('.' + settings.nextToActiveClass); | |
items.$prevToActive = items.$current.filter('.' + settings.prevToActiveClass); | |
} | |
function updateStageWidth () { | |
// give it a little extra wiggle room | |
$stage.width(getCollectionWidth(items.$current)*2); | |
} | |
function updateToMobileView () { | |
$carousel.trigger('carousel.update-to-mobile.start'); | |
mobileViewActive = true; | |
$carousel.addClass(settings.mobileViewClass); | |
settings.imageDriven && setImageDrivenWidth(true); | |
forceItemNum.width = $viewport.width(); | |
resetPosition(); | |
// ___ alert completion ___ | |
removeFromReadyQueue('mobile'); | |
$carousel.trigger('carousel.update-to-mobile.complete'); | |
} | |
function escapeMobileView () { | |
mobileViewActive = false; | |
$carousel.removeClass(settings.mobileViewClass); | |
forceItemNum.width = false; | |
settings.imageDriven && setImageDrivenWidth(); | |
resetPosition(); | |
} | |
function resetPosition () { | |
pauseAutoplay(); | |
updateCurrentItems(); | |
$carousel.addClass(settings.pauseAnimationClass); | |
// ___ Reset Values ___ | |
var newItemWidth = (forceItemNum.width) ? forceItemNum.width : ''; | |
stage.offset = 0; | |
stage.margin = 0; | |
// ___ Make all the carousel items the same width for mobile. | |
items.$current.css({ 'width' : newItemWidth }); | |
var offset = getCollectionWidth(items.$active.prevAll()); | |
updateStageWidth(); | |
moveStage(offset, false, resumeAutoplay); | |
$carousel.removeClass(settings.pauseAnimationClass); | |
} | |
function updateStageMargin (margin) { | |
$stage.css({ 'margin-left' : ( parseFloat(margin) + 'px' ) }); | |
} | |
// ___ Calculating ____ | |
function getItemWidth (item) { | |
return $(item).outerWidth(true); | |
} | |
function getCollectionWidth (collection) { | |
var collectionWidth = 0; | |
$(collection).each(function(){ | |
collectionWidth += getItemWidth(this); | |
}); | |
return collectionWidth; | |
} | |
// ___ Auto Play Functions ____ | |
function startAutoplay () { | |
if (autoplay.initialized && !autoplay.paused) { | |
$carousel.trigger('carousel.autoplay.start'); | |
autoplay.timeout = setTimeout(function(){ | |
moveNext(); | |
startAutoplay(); | |
}, settings.autoplaySpeed); | |
} | |
} | |
function pauseAutoplay () { | |
if (!autoplay.paused) { | |
clearTimeout(autoplay.timeout); | |
autoplay.paused = true; | |
$carousel.trigger('carousel.autoplay.pause'); | |
} | |
} | |
function resumeAutoplay () { | |
if (autoplay.paused) { | |
autoplay.paused = false; | |
startAutoplay(); | |
} | |
} | |
// ___ Movement Stage ___ | |
function moveStage (distance, backward, callback) { | |
// Alert all those who need to know | |
$carousel.trigger('carousel.move-stage.start'); | |
// Get the number to manipulate and any units ('px' is default) | |
var distNumber = parseFloat(distance); | |
// Moving forward or backward | |
var offset = (!backward) ? -1 * (distNumber) : distNumber; | |
var newPosition = stage.offset + offset; | |
stage.offset = newPosition; | |
updateStagePosition(newPosition, callback); | |
settings.loop && updateStageMargin(stage.margin); | |
} | |
function updateStagePosition (distance, callback) { | |
// If browser supports css translate3d | |
if ($html.hasClass('csstransforms3d')) { | |
$stage | |
.css({ | |
'transform' : 'translate3d('+ distance +'px, 0px, 0px)' | |
}); | |
} | |
else { | |
$stage | |
.css({ | |
'left' : distance +'px' | |
}); | |
} | |
$stage.on('transitionend', function(){ | |
$carousel.trigger('carousel.move-stage.complete'); | |
callback && callback(); | |
$stage.off('transitionend'); | |
}); | |
} | |
function getItemsToMove (backwards) { | |
/** | |
* Returns a jQuery Object from items.$active to moveBy number | |
* */ | |
var $itemsToMove = (backwards) ? items.$nextActive.nextUntil(items.$active).andSelf() : items.$active.nextUntil(items.$nextActive).andSelf(); | |
return $itemsToMove; | |
} | |
function setNextActive (backwards) { | |
if (!backwards) { | |
var $nextSiblings = items.$active.nextAll().andSelf(); | |
if ( $nextSiblings.length > settings.moveBy ) { | |
items.$nextActive = $nextSiblings.filter(':eq(' + settings.moveBy + ')'); | |
} | |
else if (!items.$active.is(':last-child')) { | |
// todo: make this... smarter? if the last item is already in view, we don't want to keep moving forward | |
items.$nextActive = items.$active.next(); | |
} | |
else { | |
items.$nextActive = false; | |
} | |
} | |
else { | |
var $prevSiblings = items.$active.prevAll().andSelf(); | |
if ( $prevSiblings.length > settings.moveBy ) { | |
items.$nextActive = items.$current.filter(':eq('+ (items.$active.index() - settings.moveBy) +')'); | |
} | |
else if (!items.$active.is(':first-child')) { | |
items.$nextActive = items.$active.prev(); | |
} | |
else { | |
items.$nextActive = false; | |
} | |
} | |
} | |
function move (backwards){ | |
// ___ Bust cache of items state __ | |
updateCurrentItems(); | |
setNextActive(backwards); | |
// ___ Adjust the classes ___ | |
if (items.$nextActive) { | |
removeItemClasses(); | |
setItemClasses(backwards); | |
var $itemsToMove = getItemsToMove(backwards); | |
var offset = getCollectionWidth($itemsToMove); | |
// ___ Make the shift ___ | |
if (settings.loop) { | |
/* change this based on value of backwards*/ | |
if (backwards) { | |
var $toRelocate = items.$current.last().prevAll(':lt('+((settings.moveBy - 1))+')').andSelf(); | |
stage.margin -= parseFloat(getCollectionWidth($toRelocate)); | |
$toRelocate.prependTo($stage); | |
} | |
else { | |
var $toRelocate = items.$current.first().nextAll().andSelf().filter(':lt(' + settings.moveBy + ')'); | |
stage.margin += parseFloat(getCollectionWidth($toRelocate)); | |
$toRelocate.appendTo($stage); | |
} | |
} | |
moveStage(offset, backwards); | |
} | |
} | |
function moveNext () { | |
move(false); | |
} | |
function movePrev () { | |
move(true); | |
} | |
function setItemClasses () { | |
items.$nextActive.addClass(settings.activeClass).next().addClass(settings.nextToActiveClass); | |
items.$nextActive.prev().addClass(settings.prevToActiveClass); | |
} | |
function removeItemClasses () { | |
items.$active.removeClass(settings.activeClass); | |
items.$nextToActive.removeClass(settings.nextToActiveClass); | |
items.$prevToActive.removeClass(settings.prevToActiveClass); | |
} | |
function getInQueue () { | |
return carouselReadyQueue; | |
} | |
////////// === Execute Scripts === ////////// | |
preInitialize(); | |
// $window.load(initialize); | |
return { | |
move : moveStage, | |
next : moveNext, | |
prev : movePrev, | |
pauseAutoplay : pauseAutoplay, | |
resumeAutoplay : resumeAutoplay, | |
queue : getInQueue, | |
reset : resetPosition | |
}; | |
} | |
})(window.jQuery, window, document); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment