Created
April 30, 2016 02:16
-
-
Save jshakes/68345bee3365a18cd165ae5dcfe83e6f to your computer and use it in GitHub Desktop.
Slideshow
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
/* | |
Slideshow Component | |
----------------- | |
An extensible class for adding slideshow functionality to a group of elements. Supports next/prev buttons, | |
autoplay and counter elements for showing the current and total number of slides. | |
@ $slides (jQuery el) - The element containing the slides (jQuery object) | |
@ $nextButton (jQuery el) - The forward button | |
@ $prevButton (jQuery el) - The previous button | |
@ $counterCurrent (jQuery el) - The element to display the current slide | |
@ $counterTotal (jQuery el) - The element to display the total number of slides | |
@ autoPlay (int|bool) - Speed to autoplay the slides in ms, or false turns off autoplay | |
@ firstSlide (int) - Which slide to start on (defaults to 0) | |
@ loopForwards (bool) - Whether we should restart the slideshow when we go past the last slide | |
@ loopBackwards (bool) - Whether we should go the end of the slideshow when we go past the first slide | |
*/ | |
function Slideshow(data) { | |
/* | |
Set properties from the data object | |
*/ | |
this.$slides = data.$slides | |
this.$nextButton = typeof(data.$nextButton) != "undefined" ? data.$nextButton : []; | |
this.$prevButton = typeof(data.$prevButton) != "undefined" ? data.$prevButton : []; | |
this.$counterCurrent = typeof(data.$counterCurrent) != "undefined" ? data.$counterCurrent : false; | |
this.$counterTotal = typeof(data.$counterTotal) != "undefined" ? data.$counterTotal : false; | |
this.autoPlay = data.autoPlay ? data.autoPlay : false; | |
this.firstSlide = typeof(data.firstSlide) === "number" ? data.firstSlide : 0; | |
this.loopForwards = data.loopForwards ? true : false; | |
this.loopBackwards = data.loopBackwards ? true : false; | |
this.$items = this.$slides.find("> *"); | |
this.currIndex = this.firstSlide; | |
this.maxIndex = this.$items.length; | |
/* | |
Set up bindings | |
*/ | |
_this = this; | |
if(this.$nextButton.length){ | |
this.$nextButton.on("click.advance", $.proxy(this.advance, this)); | |
} | |
if(this.$prevButton.length){ | |
this.$prevButton.on("click.recede", $.proxy(this.recede, this)); | |
} | |
if(this.$counterCurrent.length){ | |
// Update the counter when the slideshow is updated | |
this.$slides.on("recalc:slideshow", $.proxy(this.setCounterCurrent, this)); | |
} | |
if(this.$counterTotal.length){ | |
this.setCounterTotal(); | |
} | |
_.defer(function(){ | |
// Start the gallery | |
_this.$slides.trigger("initialize:slideshow"); | |
_this.recalculateGallery(true); | |
}); | |
return this; | |
}; | |
/* | |
Autoplay slideshow | |
*/ | |
Slideshow.prototype.initAutoPlay = function(ms) { | |
var _this = this; | |
if (this.timerID) { | |
clearTimeout(this.timerID); | |
} | |
return this.timerID = setTimeout((function() { | |
return _this.advance(); | |
}), ms); | |
}; | |
/* | |
Movement Functions | |
*/ | |
/* | |
Set current index field to the next slide position | |
*/ | |
Slideshow.prototype.advance = function() { | |
this.currIndex++; | |
if (this.currIndex + 1 > this.maxIndex) { | |
this.handleMaxLimit(); | |
} | |
else { | |
this.recalculateGallery(); | |
} | |
}; | |
/* | |
Set current index field to the previous slide position | |
*/ | |
Slideshow.prototype.recede = function() { | |
this.currIndex--; | |
if (this.currIndex < 0) { | |
this.handleMinLimit(); | |
} | |
else { | |
this.recalculateGallery(); | |
} | |
}; | |
/* | |
Set current index field to the arguments position | |
*/ | |
Slideshow.prototype.gotoIndex = function(index) { | |
this.currIndex = index; | |
return this.recalculateGallery(); | |
}; | |
Slideshow.prototype.goToStart = function() { | |
return this.gotoIndex(0); | |
}; | |
Slideshow.prototype.goToEnd = function() { | |
return this.gotoIndex(this.maxIndex); | |
}; | |
/* | |
When the final slide is reached, trigger the maxLimit event and go back to the beginning if this.loopForwards == true | |
*/ | |
Slideshow.prototype.handleMaxLimit = function() { | |
this.$slides.trigger("maxLimit:slideshow"); | |
if(this.loopForwards){ | |
return this.goToStart(); | |
} | |
else{ | |
this.currIndex = this.maxLimit - 1; | |
} | |
}; | |
/* | |
When the first slide is reached, trigger the minLimit event and go to the end if this.loopBackwards == true | |
*/ | |
Slideshow.prototype.handleMinLimit = function() { | |
this.$slides.trigger("minLimit:slideshow"); | |
if(this.loopBackwards){ | |
return this.goToEnd(); | |
} | |
else{ | |
this.currIndex = 0; | |
} | |
}; | |
/* | |
Apply classes based upon current position field | |
Note: Doesn't cause a reflow - all the slides are out of the document flow. | |
*/ | |
Slideshow.prototype.recalculateGallery = function(init) { | |
var _this = this; | |
$.each(this.$items, function(i, el){ | |
if (i < _this.currIndex) { | |
$(el).addClass('passed').removeClass("current upcoming"); | |
} | |
if (i === _this.currIndex) { | |
$(el).addClass('current').removeClass("passed upcoming").trigger('isCurrent'); | |
} | |
if (i > _this.currIndex) { | |
$(el).addClass('upcoming').removeClass("passed current"); | |
} | |
}); | |
/* | |
Reset the autoplay | |
*/ | |
if(typeof(this.autoPlay) === "number"){ | |
this.initAutoPlay(this.autoPlay); | |
} | |
/* | |
Fire events | |
*/ | |
this.$slides.trigger("recalc:slideshow", this); | |
}; | |
Slideshow.prototype.getCurrentItem = function() { | |
return this.$items[this.currIndex]; | |
}; | |
Slideshow.prototype.getCurrentIndex = function() { | |
return this.currIndex; | |
}; | |
Slideshow.prototype.setCounterTotal = function() { | |
return this.$counterTotal.text(this.maxIndex); | |
}; | |
Slideshow.prototype.setCounterCurrent = function() { | |
return this.$counterCurrent.text(this.currIndex + 1); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment