diff --git a/dist/jquery.slotmachine.js b/dist/jquery.slotmachine.js
index 46fe2f5..8ff567e 100644
--- a/dist/jquery.slotmachine.js
+++ b/dist/jquery.slotmachine.js
@@ -1,565 +1,563 @@
/*! SlotMachine - v2.0.11 - 2015-07-21
* https://github.com/josex2r/jQuery-SlotMachine
* Copyright (c) 2015 Jose Luis Represa; Licensed MIT */
-;(function($, window, document, undefined){
-
- var pluginName = "slotMachine",
- defaults = {
- active : 0, //Active element [int]
- delay : 200, //Animation time [int]
- auto : false, //Repeat delay [false||int]
- randomize : null, //Randomize function, must return an integer with the selected position
- complete : null, //Callback function(result)
- stopHidden : true //Stops animations if the element isn´t visible on the screen
- };
-
- var FX_FAST = 'slotMachineBlurFast',
- FX_NORMAL = 'slotMachineBlurMedium',
- FX_SLOW = 'slotMachineBlurSlow',
- FX_GRADIENT = 'slotMachineGradient',
- FX_STOP = FX_GRADIENT;
-
- //Set required styles, filters and masks
- $(document).ready(function(){
-
- var slotMachineBlurFilterFastString = '#slotMachineBlurFilterFast';
-
- var slotMachineBlurFilterMediumString = '#slotMachineBlurFilterMedium';
-
- var slotMachineBlurFilterSlowString = '#slotMachineBlurFilterSlow';
-
- var slotMachineFadeMaskString = '#slotMachineFadeMask';
-
- //CSS classes
- $('body').append('');
-
- });
-
- //Required easing functions
- if(typeof $.easing.easeOutBounce !== 'function'){
- //From jQuery easing, extend jQuery animations functions
- $.extend( $.easing, {
- easeOutBounce: function (x, t, b, c, d) {
- if ((t/=d) < (1/2.75)) {
- return c*(7.5625*t*t) + b;
- } else if (t < (2/2.75)) {
- return c*(7.5625*(t-=(1.5/2.75))*t + 0.75) + b;
- } else if (t < (2.5/2.75)) {
- return c*(7.5625*(t-=(2.25/2.75))*t + 0.9375) + b;
- } else {
- return c*(7.5625*(t-=(2.625/2.75))*t + 0.984375) + b;
- }
- },
- });
- }
-
-
- function Timer(fn, delay){
- var startTime,
- self = this,
- timer,
- _fn = fn,
- _args = arguments,
- _delay = delay;
-
- this.running = false;
-
- this.onpause = function(){};
- this.onresume = function(){};
-
- this.cancel = function(){
- this.running = false;
- clearTimeout(timer);
- };
-
- this.pause = function(){
- if( this.running ){
- delay -= new Date().getTime() - startTime;
- this.cancel();
- this.onpause();
- }
- };
-
- this.resume = function(){
- if( !this.running ){
- this.running = true;
- startTime = new Date().getTime();
-
- timer = setTimeout(function(){
- _fn.apply(self, Array.prototype.slice.call(_args, 2, _args.length)); //Execute function with initial arguments, removing (fn & delay)
- }, delay);
-
- this.onresume();
- }
- };
-
- this.reset = function(){
- this.cancel();
- this.running = true;
- delay = _delay;
- timer = setTimeout(function(){
- _fn.apply(self, Array.prototype.slice.call(_args, 2, _args.length)); //Execute function with initial arguments, removing (fn & delay)
- }, _delay);
- };
-
- this.add = function(extraDelay){
- this.pause();
- delay += extraDelay;
- this.resume();
+(function($, window, document, undefined) {
+
+ var pluginName = "slotMachine",
+ defaults = {
+ active: 0, //Active element [int]
+ delay: 200, //Animation time [int]
+ auto: false, //Repeat delay [false||int]
+ spins: 5, //Number of spins when auto [int]
+ randomize: null, //Randomize function, must return an integer with the selected position
+ complete: null, //Callback function(result)
+ stopHidden: true //Stops animations if the element isn´t visible on the screen
};
-
- this.resume();
- }
-
-
- /**
- * @desc PUBLIC - Makes Slot Machine animation effect
- * @param DOM element - Html element
- * @param object settings - Plugin configuration params
- * @return jQuery node - Returns jQuery selector with some new functions (shuffle, stop, next, auto, active)
- */
- function SlotMachine(element, options){
- this.element = element;
- this.settings = $.extend( {}, defaults, options);
- this.defaults = defaults;
- this.name = pluginName;
-
- //jQuery selector
- this.$slot = $(element);
- //Slot Machine elements
- this.$tiles = this.$slot.children();
- //Container to wrap $tiles
- this.$container = null;
- //Min marginTop offset
- this._minTop = null;
- //Max marginTop offset
- this._maxTop = null;
- //First element (the last of the html container)
- this._$fakeFirstTile = null;
- //Last element (the first of the html container)
- this._$fakeLastTile = null;
- //Timeout recursive function to handle auto (settings.auto)
- this._timer = null;
- //Callback function
- this._oncompleteStack = [ this.settings.complete ];
- //Number of spins left before stop
- this._spinsLeft = null;
- //Future result
- this.futureActive = null;
- //Machine is running?
- this.isRunning = false;
- //Machine is stopping?
- this.isStopping = false;
- //Current active element
- this.active = this.settings.active;
-
- this.$slot.css("overflow", "hidden");
-
- //Validate active index
- if(this.settings.active < 0 || this.settings.active >= this.$tiles.length ){
- this.settings.active = 0;
- this.active = 0;
- }
-
- //Wrap elements inside $container
- this.$tiles.wrapAll("
");
- this.$container = this.$slot.find(".slotMachineContainer");
-
- //Set max top offset
- this._maxTop = - this.$container.height();
-
- //Add the last element behind the first to prevent the jump effect
- this._$fakeFirstTile = this.$tiles.last().clone();
- this._$fakeLastTile = this.$tiles.first().clone();
-
- this.$container.prepend( this._$fakeFirstTile );
- this.$container.append( this._$fakeLastTile );
-
- //Set min top offset
- this._minTop = - this._$fakeFirstTile.outerHeight();
-
- //Show active element
- this.$container.css('margin-top', this.getTileOffset(this.active));
-
- //Start auto animation
- if(this.settings.auto !== false){
- if(this.settings.auto === true){
- this.shuffle();
- }else{
- this.auto();
- }
- }
- }
- /**
- * @desc PRIVATE - Get element offset top
- * @param int index - Element position
- * @return int - Negative offset in px
- */
- SlotMachine.prototype.getTileOffset = function(index){
- var offset = 0;
- for(var i=0; i= 0);
-
- return rnd;
- };
- /**
- * @desc PRIVATE - Get random element based on the custom randomize function
- * @return int - Element index
- */
- SlotMachine.prototype.getCustom = function(){
- var choosen;
- if(this.settings.randomize !== null && typeof this.settings.randomize === 'function'){
- var index = this.settings.randomize.apply(this, [this.active]);
- if(index < 0 || index >= this.$tiles.length){
- index = 0;
- }
- choosen = index;
- }else{
- choosen = this.getRandom();
- }
- return choosen;
- };
- /**
- * @desc PRIVATE - Get the previous element
- * @return int - Element index
- */
- SlotMachine.prototype.getPrev = function(){
- var prevIndex = (this.active-1 < 0) ? (this.$tiles.length - 1) : (this.active - 1);
- return prevIndex;
- };
- /**
- * @desc PRIVATE - Get the next element
- * @return int - Element index
- */
- SlotMachine.prototype.getNext = function(){
- var nextIndex = (this.active + 1 < this.$tiles.length) ? (this.active + 1) : 0;
- return nextIndex;
- };
- /**
- * @desc PRIVATE - Set CSS classes to make speed effect
- * @param string FX_SPEED - Element speed [FX_FAST_BLUR||FX_NORMAL_BLUR||FX_SLOW_BLUR||FX_STOP]
- * @param string||boolean fade - Set fade gradient effect
- */
- SlotMachine.prototype._setAnimationFX = function(FX_SPEED, fade){
- var self = this;
-
- setTimeout(function(){
- self.$tiles.removeClass(FX_FAST).removeClass(FX_NORMAL).removeClass(FX_SLOW).addClass(FX_SPEED);
-
- if(fade !== true || FX_SPEED === FX_STOP){
- self.$slot.add(self.$tiles).removeClass(FX_GRADIENT);
- }else{
- self.$slot.add(self.$tiles).addClass(FX_GRADIENT);
- }
- }, this.settings.delay / 4);
- };
- /**
- * @desc PRIVATE - Reset active element position
- */
- SlotMachine.prototype._resetPosition = function(){
- this.$container.css("margin-top", this.getTileOffset(this.active));
- };
- /**
- * @desc PRIVATE - Checks if the machine is on the screen
- * @return int - Returns true if machine is on the screen
- */
- SlotMachine.prototype.isVisible = function(){
- //Stop animation if element is [above||below] screen, best for performance
- var above = this.$slot.offset().top > $(window).scrollTop() + $(window).height(),
- below = $(window).scrollTop() > this.$slot.height() + this.$slot.offset().top;
-
- return !above && !below;
- };
- /**
- * @desc PUBLIC - SELECT previous element relative to the current active element
- * @return int - Returns result index
- */
- SlotMachine.prototype.prev = function(){
- this.futureActive = this.getPrev();
- this.isRunning = true;
- this.stop(false);
- return this.futureActive;
- };
- /**
- * @desc PUBLIC - SELECT next element relative to the current active element
- * @return int - Returns result index
- */
- SlotMachine.prototype.next = function(){
- this.futureActive = this.getNext();
- this.isRunning = true;
- this.stop(false);
- return this.futureActive;
- };
- /**
- * @desc PRIVATE - Starts shuffling the elements
- * @param int repeations - Number of shuffles (undefined to make infinite animation
- * @return int - Returns result index
- */
- SlotMachine.prototype.shuffle = function( spins, onComplete ){
- var self = this;
-
- if(onComplete !== undefined){
- //this._oncompleteStack.push(onComplete);
- this._oncompleteStack[1] = onComplete;
- }
-
- this.isRunning = true;
- var delay = this.settings.delay;
-
- if(this.futureActive === null){
- //Get random or custom element
- var rnd = this.getCustom();
- this.futureActive = rnd;
- }
-
- /*if(this.$slot.attr("id")==="machine1")
- console.log(this.futureActive)*/
- //Decreasing spin
- if(typeof spins === 'number'){
- //Change delay and speed
- switch( spins){
- case 1:
- case 2:
- this._setAnimationFX(FX_SLOW, true);
- break;
- case 3:
- case 4:
- this._setAnimationFX(FX_NORMAL, true);
- delay /= 1.5;
- break;
- default:
- this._setAnimationFX(FX_FAST, true);
- delay /= 2;
- }
- //Infinite spin
- }else{
- //Set animation effects
- this._setAnimationFX(FX_FAST, true);
- delay /= 2;
- }
-
- //Perform animation
- if(!this.isVisible() && this.settings.stopHidden === true){
- spins = 0;
- self.stop();
- }else{
- this.$container.animate({
- marginTop : this._maxTop
- }, delay, 'linear', function(){
- //Reset top position
- self.$container.css('margin-top', 0);
-
- if(spins - 1 <= 0){
- self.stop();
- }else{
- //Repeat animation
- self.shuffle(spins - 1);
- }
- });
- }
-
- return this.futureActive;
- };
- /**
- * @desc PRIVATE - Stop shuffling the elements
- * @return int - Returns result index
- */
- SlotMachine.prototype.stop = function( showGradient ){
- if(!this.isRunning){
- return;
- } else if (this.isStopping) {
- return this.futureActive;
- }
- var self = this;
-
- //Stop animation NOW!!!!!!!
- this.$container.clearQueue().stop(true, false);
-
- this._setAnimationFX(FX_SLOW, showGradient === undefined ? true : showGradient);
-
- this.isRunning = true;
- this.isStopping = true;
-
- //Set current active element
- this.active = this.getVisibleTile();
-
- //Check direction to prevent jumping
- if(this.futureActive > this.active){
- //We are moving to the prev (first to last)
- if(this.active === 0 && this.futureActive === this.$tiles.length-1){
- this.$container.css('margin-top', this.getTileOffset(this.$tiles.length) );
- }
- }else{
- //We are moving to the next (last to first)
- if(this.active === this.$tiles.length - 1 && this.futureActive === 0){
- this.$container.css('margin-top', 0);
- }
- }
-
- //Update last choosen element index
- this.active = this.futureActive;
-
- //Get delay
- var delay = this.settings.delay * 3;
-
- //Perform animation
- this.$container.animate({
- marginTop : this.getTileOffset(this.active)
- }, delay, 'easeOutBounce', function (){
-
- self.isStopping = false;
- self.isRunning = false;
- self.futureActive = null;
-
- //Filter callbacks
- /*
- self._oncompleteStack = Array.prototype.filter.call(self._oncompleteStack, function(fn){
- return typeof fn === 'function';
- });
- //Ececute callbacks
- Array.prototype.map.call(self._oncompleteStack, function(fn, index){
- if(typeof fn === 'function'){
- fn.apply(self, [self.active]);
- self._oncompleteStack[index] = null;
- }
- });
- */
- if(typeof self._oncompleteStack[0] === 'function'){
- self._oncompleteStack[0].apply(self, [self.active]);
- }
- if(typeof self._oncompleteStack[1] === 'function'){
- self._oncompleteStack[1].apply(self, [self.active]);
- }
- });
-
- //Disable blur
- setTimeout(function(){
- self._setAnimationFX(FX_STOP, false);
- }, delay / 1.75);
-
- return this.active;
- };
- /**
- * @desc PRIVATE - Start auto shufflings, animation stops each 3 repeations. Then restart animation recursively
- */
- SlotMachine.prototype.auto = function(){
- var self = this;
-
- this._timer = new Timer(function(){
- if(typeof self.settings.randomize !== 'function'){
- self.futureActive = self.getNext();
- }
- self.isRunning = true;
- if(!self.isVisible() && self.settings.stopHidden === true){
- setTimeout(function(){
- self._timer.reset();
- }, 500);
- }else{
- self.shuffle(5, function(){
- self._timer.reset();
- });
- }
-
- }, this.settings.auto);
- };
-
-
-
- /*
- * Create new plugin instance if needed and return it
- */
- function _getInstance(element, options){
- var machine;
- if ( !$.data(element[0], 'plugin_' + pluginName) ){
- machine = new SlotMachine(element, options);
- $.data(element[0], 'plugin_' + pluginName, machine);
- }else{
- machine = $.data(element[0], 'plugin_' + pluginName);
- }
- return machine;
- }
-
- /*
- * Chainable instance
- */
- $.fn[pluginName] = function(options){
- if( this.length===1 ){
- return _getInstance(this, options);
- }else{
- return this.each(function(){
- if( !$.data(this, 'plugin_' + pluginName) ){
- _getInstance(this, options);
- }
- });
- }
- };
-
-})( jQuery, window, document );
+
+ var FX_FAST = 'slotMachineBlurFast',
+ FX_NORMAL = 'slotMachineBlurMedium',
+ FX_SLOW = 'slotMachineBlurSlow',
+ FX_GRADIENT = 'slotMachineGradient',
+ FX_STOP = FX_GRADIENT;
+
+ //Set required styles, filters and masks
+ $(document).ready(function() {
+
+ var slotMachineBlurFilterFastString = '#slotMachineBlurFilterFast';
+
+ var slotMachineBlurFilterMediumString = '#slotMachineBlurFilterMedium';
+
+ var slotMachineBlurFilterSlowString = '#slotMachineBlurFilterSlow';
+
+ var slotMachineFadeMaskString = '#slotMachineFadeMask';
+
+ //CSS classes
+ $('body').append('');
+
+ });
+
+ //Required easing functions
+ if (typeof $.easing.easeOutBounce !== 'function') {
+ //From jQuery easing, extend jQuery animations functions
+ $.extend($.easing, {
+ easeOutBounce: function(x, t, b, c, d) {
+ if ((t /= d) < (1 / 2.75)) {
+ return c * (7.5625 * t * t) + b;
+ } else if (t < (2 / 2.75)) {
+ return c * (7.5625 * (t -= (1.5 / 2.75)) * t + 0.75) + b;
+ } else if (t < (2.5 / 2.75)) {
+ return c * (7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375) + b;
+ } else {
+ return c * (7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375) + b;
+ }
+ },
+ });
+ }
+
+
+ function Timer(fn, delay) {
+ var startTime,
+ self = this,
+ timer,
+ _fn = fn,
+ _args = arguments,
+ _delay = delay;
+
+ this.running = false;
+
+ this.onpause = function() {};
+ this.onresume = function() {};
+
+ this.cancel = function() {
+ this.running = false;
+ clearTimeout(timer);
+ };
+
+ this.pause = function() {
+ if (this.running) {
+ delay -= new Date().getTime() - startTime;
+ this.cancel();
+ this.onpause();
+ }
+ };
+
+ this.resume = function() {
+ if (!this.running) {
+ this.running = true;
+ startTime = new Date().getTime();
+
+ timer = setTimeout(function() {
+ _fn.apply(self, Array.prototype.slice.call(_args, 2, _args.length)); //Execute function with initial arguments, removing (fn & delay)
+ }, delay);
+
+ this.onresume();
+ }
+ };
+
+ this.reset = function() {
+ this.cancel();
+ this.running = true;
+ delay = _delay;
+ timer = setTimeout(function() {
+ _fn.apply(self, Array.prototype.slice.call(_args, 2, _args.length)); //Execute function with initial arguments, removing (fn & delay)
+ }, _delay);
+ };
+
+ this.add = function(extraDelay) {
+ this.pause();
+ delay += extraDelay;
+ this.resume();
+ };
+
+ this.resume();
+ }
+
+
+ /**
+ * @desc PUBLIC - Makes Slot Machine animation effect
+ * @param DOM element - Html element
+ * @param object settings - Plugin configuration params
+ * @return jQuery node - Returns jQuery selector with some new functions (shuffle, stop, next, auto, active)
+ */
+ function SlotMachine(element, options) {
+ this.element = element;
+ this.settings = $.extend({}, defaults, options);
+ this.defaults = defaults;
+ this.name = pluginName;
+
+ //jQuery selector
+ this.$slot = $(element);
+ //Slot Machine elements
+ this.$tiles = this.$slot.children();
+ //Container to wrap $tiles
+ this.$container = null;
+ //Min marginTop offset
+ this._minTop = null;
+ //Max marginTop offset
+ this._maxTop = null;
+ //First element (the last of the html container)
+ this._$fakeFirstTile = null;
+ //Last element (the first of the html container)
+ this._$fakeLastTile = null;
+ //Timeout recursive function to handle auto (settings.auto)
+ this._timer = null;
+ //Callback function
+ this._oncompleteStack = [this.settings.complete];
+ //Number of spins left before stop
+ this._spinsLeft = null;
+ //Future result
+ this.futureActive = null;
+ //Machine is running?
+ this.isRunning = false;
+ //Machine is stopping?
+ this.isStopping = false;
+ //Current active element
+ this.active = this.settings.active;
+
+ this.$slot.css('overflow', 'hidden');
+
+ //Validate active index
+ if (this.settings.active < 0 || this.settings.active >= this.$tiles.length) {
+ this.settings.active = 0;
+ this.active = 0;
+ }
+
+ //Wrap elements inside $container
+ this.$container = this.$tiles.wrapAll('').parent();
+
+ //Set max top offset
+ this._maxTop = -this.$container.height();
+
+ //Add the last element behind the first to prevent the jump effect
+ this._$fakeFirstTile = this.$tiles.last().clone();
+ this._$fakeLastTile = this.$tiles.first().clone();
+
+ this.$container.prepend(this._$fakeFirstTile);
+ this.$container.append(this._$fakeLastTile);
+
+ //Set min top offset
+ this._minTop = -this._$fakeFirstTile.outerHeight();
+
+ //Show active element
+ this.$container.css('margin-top', this.getTileOffset(this.active));
+
+ //Start auto animation
+ if (this.settings.auto !== false) {
+ if (this.settings.auto === true) {
+ this.shuffle();
+ } else {
+ this.auto();
+ }
+ }
+ }
+
+ /**
+ * @desc PRIVATE - Get element offset top
+ * @param int index - Element position
+ * @return int - Negative offset in px
+ */
+ SlotMachine.prototype.getTileOffset = function(index) {
+ var offset = 0;
+ for (var i = 0; i < index; i++) {
+ offset += this.$tiles.eq(i).outerHeight();
+ }
+ return -offset + this._minTop;
+ };
+
+ /**
+ * @desc PRIVATE - Get current showing element index
+ * @return int - Element index
+ */
+ SlotMachine.prototype.getVisibleTile = function() {
+ var firstTileHeight = this.$tiles.first().height(),
+ containerMarginTop = parseInt(this.$container.css('margin-top').replace(/px/, ''), 10);
+
+ return Math.abs(Math.round(containerMarginTop / firstTileHeight)) - 1;
+ };
+
+ /**
+ * @desc PUBLIC - Changes randomize function
+ * @param function|int - Set new randomize function
+ */
+ SlotMachine.prototype.setRandomize = function(rnd) {
+ if (typeof rnd === 'number') {
+ this.settings.randomize = function() {
+ return rnd;
+ };
+ } else {
+ this.settings.randomize = rnd;
+ }
+ };
+
+ /**
+ * @desc PRIVATE - Get random element different than last shown
+ * @param boolean cantBeTheCurrent - true||undefined if cant be choosen the current element, prevents repeat
+ * @return int - Element index
+ */
+ SlotMachine.prototype.getRandom = function(cantBeTheCurrent) {
+ var rnd,
+ removePrevious = cantBeTheCurrent || false;
+ do {
+ rnd = Math.floor(Math.random() * this.$tiles.length);
+ } while ((removePrevious && rnd === this.active) && rnd >= 0);
+
+ return rnd;
+ };
+
+ /**
+ * @desc PRIVATE - Get random element based on the custom randomize function
+ * @return int - Element index
+ */
+ SlotMachine.prototype.getCustom = function() {
+ var choosen;
+ if (this.settings.randomize !== null && typeof this.settings.randomize === 'function') {
+ var index = this.settings.randomize.apply(this, [this.active]);
+ if (index < 0 || index >= this.$tiles.length) {
+ index = 0;
+ }
+ choosen = index;
+ } else {
+ choosen = this.getRandom();
+ }
+ return choosen;
+ };
+
+ /**
+ * @desc PRIVATE - Get the previous element
+ * @return int - Element index
+ */
+ SlotMachine.prototype.getPrev = function() {
+ var prevIndex = (this.active - 1 < 0) ? (this.$tiles.length - 1) : (this.active - 1);
+ return prevIndex;
+ };
+
+ /**
+ * @desc PRIVATE - Get the next element
+ * @return int - Element index
+ */
+ SlotMachine.prototype.getNext = function() {
+ var nextIndex = (this.active + 1 < this.$tiles.length) ? (this.active + 1) : 0;
+ return nextIndex;
+ };
+
+ /**
+ * @desc PRIVATE - Set CSS classes to make speed effect
+ * @param string FX_SPEED - Element speed [FX_FAST_BLUR||FX_NORMAL_BLUR||FX_SLOW_BLUR||FX_STOP]
+ * @param string||boolean fade - Set fade gradient effect
+ */
+ SlotMachine.prototype._setAnimationFX = function(FX_SPEED, fade) {
+ var self = this;
+
+ setTimeout(function() {
+ self.$tiles.removeClass([FX_FAST, FX_NORMAL, FX_SLOW].join(' ')).addClass(FX_SPEED);
+
+ if (fade !== true || FX_SPEED === FX_STOP) {
+ self.$slot.add(self.$tiles).removeClass(FX_GRADIENT);
+ } else {
+ self.$slot.add(self.$tiles).addClass(FX_GRADIENT);
+ }
+ }, this.settings.delay / 4);
+ };
+
+ /**
+ * @desc PRIVATE - Reset active element position
+ */
+ SlotMachine.prototype._resetPosition = function() {
+ this.$container.css('margin-top', this.getTileOffset(this.active));
+ };
+
+ /**
+ * @desc PRIVATE - Checks if the machine is on the screen
+ * @return int - Returns true if machine is on the screen
+ */
+ SlotMachine.prototype.isVisible = function() {
+ //Stop animation if element is [above||below] screen, best for performance
+ var above = this.$slot.offset().top > $(window).scrollTop() + $(window).height(),
+ below = $(window).scrollTop() > this.$slot.height() + this.$slot.offset().top;
+
+ return !above && !below;
+ };
+
+ /**
+ * @desc PUBLIC - SELECT previous element relative to the current active element
+ * @return int - Returns result index
+ */
+ SlotMachine.prototype.prev = function() {
+ this.futureActive = this.getPrev();
+ this.isRunning = true;
+ this.stop(false);
+ return this.futureActive;
+ };
+
+ /**
+ * @desc PUBLIC - SELECT next element relative to the current active element
+ * @return int - Returns result index
+ */
+ SlotMachine.prototype.next = function() {
+ this.futureActive = this.getNext();
+ this.isRunning = true;
+ this.stop(false);
+ return this.futureActive;
+ };
+
+ /**
+ * @desc PRIVATE - Starts shuffling the elements
+ * @param int repeations - Number of shuffles (undefined to make infinite animation
+ * @return int - Returns result index
+ */
+ SlotMachine.prototype.shuffle = function(spins, onComplete) {
+ var self = this;
+
+ if (onComplete !== undefined) {
+ this._oncompleteStack[1] = onComplete;
+ }
+
+ this.isRunning = true;
+ var delay = this.settings.delay;
+
+ if (this.futureActive === null) {
+ //Get random or custom element
+ var rnd = this.getCustom();
+ this.futureActive = rnd;
+ }
+
+ //Decreasing spin
+ if (typeof spins === 'number') {
+ //Change delay and speed
+ switch (spins) {
+ case 1:
+ case 2:
+ this._setAnimationFX(FX_SLOW, true);
+ break;
+ case 3:
+ case 4:
+ this._setAnimationFX(FX_NORMAL, true);
+ delay /= 1.5;
+ break;
+ default:
+ this._setAnimationFX(FX_FAST, true);
+ delay /= 2;
+ }
+ //Infinite spin
+ } else {
+ //Set animation effects
+ this._setAnimationFX(FX_FAST, true);
+ delay /= 2;
+ }
+
+ //Perform animation
+ if (!this.isVisible() && this.settings.stopHidden === true) {
+ spins = 0;
+ self.stop();
+ } else {
+ this.$container.animate({
+ marginTop: this._maxTop
+ }, delay, 'linear', function() {
+ //Reset top position
+ self.$container.css('margin-top', 0);
+
+ if (spins - 1 <= 0) {
+ self.stop();
+ } else {
+ //Repeat animation
+ self.shuffle(spins - 1);
+ }
+ });
+ }
+
+ return this.futureActive;
+ };
+
+ /**
+ * @desc PRIVATE - Stop shuffling the elements
+ * @return int - Returns result index
+ */
+ SlotMachine.prototype.stop = function(showGradient) {
+ if (!this.isRunning) {
+ return;
+ } else if (this.isStopping) {
+ return this.futureActive;
+ }
+ var self = this;
+
+ //Stop animation NOW!!!!!!!
+ this.$container.clearQueue().stop(true, false);
+
+ this._setAnimationFX(FX_SLOW, showGradient === undefined ? true : showGradient);
+
+ this.isRunning = true;
+ this.isStopping = true;
+
+ //Set current active element
+ this.active = this.getVisibleTile();
+
+ //Check direction to prevent jumping
+ if (this.futureActive > this.active) {
+ //We are moving to the prev (first to last)
+ if (this.active === 0 && this.futureActive === this.$tiles.length - 1) {
+ this.$container.css('margin-top', this.getTileOffset(this.$tiles.length));
+ }
+ } else {
+ //We are moving to the next (last to first)
+ if (this.active === this.$tiles.length - 1 && this.futureActive === 0) {
+ this.$container.css('margin-top', 0);
+ }
+ }
+
+ //Update last choosen element index
+ this.active = this.futureActive;
+
+ //Get delay
+ var delay = this.settings.delay * 3;
+
+ //Perform animation
+ this.$container.animate({
+ marginTop: this.getTileOffset(this.active)
+ }, delay, 'easeOutBounce', function() {
+
+ self.isStopping = false;
+ self.isRunning = false;
+ self.futureActive = null;
+
+ if (typeof self._oncompleteStack[0] === 'function') {
+ self._oncompleteStack[0].apply(self, [self.active]);
+ }
+ if (typeof self._oncompleteStack[1] === 'function') {
+ self._oncompleteStack[1].apply(self, [self.active]);
+ }
+ });
+
+ //Disable blur
+ setTimeout(function() {
+ self._setAnimationFX(FX_STOP, false);
+ }, delay / 1.75);
+
+ return this.active;
+ };
+
+ /**
+ * @desc PRIVATE - Start auto shufflings, animation stops each 3 repeations. Then restart animation recursively
+ */
+ SlotMachine.prototype.auto = function() {
+ var self = this;
+
+ this._timer = new Timer(function() {
+ if (typeof self.settings.randomize !== 'function') {
+ self.futureActive = self.getNext();
+ }
+ self.isRunning = true;
+ if (!self.isVisible() && self.settings.stopHidden === true) {
+ setTimeout(function() {
+ self._timer.reset();
+ }, 500);
+ } else {
+ self.shuffle(self.settings.spins, function() {
+ self._timer.reset();
+ });
+ }
+
+ }, this.settings.auto);
+ };
+
+
+
+ /*
+ * Create new plugin instance if needed and return it
+ */
+ function _getInstance(element, options) {
+ var machine;
+ if (!$.data(element[0], 'plugin_' + pluginName)) {
+ machine = new SlotMachine(element, options);
+ $.data(element[0], 'plugin_' + pluginName, machine);
+ } else {
+ machine = $.data(element[0], 'plugin_' + pluginName);
+ }
+ return machine;
+ }
+
+ /*
+ * Chainable instance
+ */
+ $.fn[pluginName] = function(options) {
+ if (this.length === 1) {
+ return _getInstance(this, options);
+ } else {
+ var $els = this;
+ return $.map($els, function(el, index) {
+ var $el = $els.eq(index);
+ return _getInstance($el, options);
+ });
+ }
+ };
+
+})(jQuery, window, document);
diff --git a/dist/jquery.slotmachine.min.js b/dist/jquery.slotmachine.min.js
index e625a3e..d2128eb 100644
--- a/dist/jquery.slotmachine.min.js
+++ b/dist/jquery.slotmachine.min.js
@@ -1,4 +1,4 @@
/*! SlotMachine - v2.0.11 - 2015-07-21
* https://github.com/josex2r/jQuery-SlotMachine
* Copyright (c) 2015 Jose Luis Represa; Licensed MIT */
-!function(a,b,c,d){function e(a,b){var c,d,e=this,f=a,g=arguments,h=b;this.running=!1,this.onpause=function(){},this.onresume=function(){},this.cancel=function(){this.running=!1,clearTimeout(d)},this.pause=function(){this.running&&(b-=(new Date).getTime()-c,this.cancel(),this.onpause())},this.resume=function(){this.running||(this.running=!0,c=(new Date).getTime(),d=setTimeout(function(){f.apply(e,Array.prototype.slice.call(g,2,g.length))},b),this.onresume())},this.reset=function(){this.cancel(),this.running=!0,b=h,d=setTimeout(function(){f.apply(e,Array.prototype.slice.call(g,2,g.length))},h)},this.add=function(a){this.pause(),b+=a,this.resume()},this.resume()}function f(b,c){this.element=b,this.settings=a.extend({},i,c),this.defaults=i,this.name=h,this.$slot=a(b),this.$tiles=this.$slot.children(),this.$container=null,this._minTop=null,this._maxTop=null,this._$fakeFirstTile=null,this._$fakeLastTile=null,this._timer=null,this._oncompleteStack=[this.settings.complete],this._spinsLeft=null,this.futureActive=null,this.isRunning=!1,this.isStopping=!1,this.active=this.settings.active,this.$slot.css("overflow","hidden"),(this.settings.active<0||this.settings.active>=this.$tiles.length)&&(this.settings.active=0,this.active=0),this.$tiles.wrapAll(""),this.$container=this.$slot.find(".slotMachineContainer"),this._maxTop=-this.$container.height(),this._$fakeFirstTile=this.$tiles.last().clone(),this._$fakeLastTile=this.$tiles.first().clone(),this.$container.prepend(this._$fakeFirstTile),this.$container.append(this._$fakeLastTile),this._minTop=-this._$fakeFirstTile.outerHeight(),this.$container.css("margin-top",this.getTileOffset(this.active)),this.settings.auto!==!1&&(this.settings.auto===!0?this.shuffle():this.auto())}function g(b,c){var d;return a.data(b[0],"plugin_"+h)?d=a.data(b[0],"plugin_"+h):(d=new f(b,c),a.data(b[0],"plugin_"+h,d)),d}var h="slotMachine",i={active:0,delay:200,auto:!1,randomize:null,complete:null,stopHidden:!0},j="slotMachineBlurFast",k="slotMachineBlurMedium",l="slotMachineBlurSlow",m="slotMachineGradient",n=m;a(c).ready(function(){var b='#slotMachineBlurFilterFast',c='#slotMachineBlurFilterMedium',d='#slotMachineBlurFilterSlow',e='#slotMachineFadeMask';a("body").append("')}),"function"!=typeof a.easing.easeOutBounce&&a.extend(a.easing,{easeOutBounce:function(a,b,c,d,e){return(b/=e)<1/2.75?7.5625*d*b*b+c:2/2.75>b?d*(7.5625*(b-=1.5/2.75)*b+.75)+c:2.5/2.75>b?d*(7.5625*(b-=2.25/2.75)*b+.9375)+c:d*(7.5625*(b-=2.625/2.75)*b+.984375)+c}}),f.prototype.getTileOffset=function(b){for(var c=0,d=0;b>d;d++)c+=a(this.$tiles.get(d)).outerHeight();return-c+this._minTop},f.prototype.getVisibleTile=function(){var a=this.$tiles.first().height(),b=parseInt(this.$container.css("margin-top").replace(/px/,""),10);return Math.abs(Math.round(b/a))-1},f.prototype.setRandomize=function(a){if("number"==typeof a){var b=function(){return a};this.settings.randomize=b}else this.settings.randomize=a},f.prototype.getRandom=function(a){var b,c=a||!1;do b=Math.floor(Math.random()*this.$tiles.length);while(c&&b===this.active&&b>=0);return b},f.prototype.getCustom=function(){var a;if(null!==this.settings.randomize&&"function"==typeof this.settings.randomize){var b=this.settings.randomize.apply(this,[this.active]);(0>b||b>=this.$tiles.length)&&(b=0),a=b}else a=this.getRandom();return a},f.prototype.getPrev=function(){var a=this.active-1<0?this.$tiles.length-1:this.active-1;return a},f.prototype.getNext=function(){var a=this.active+1a(b).scrollTop()+a(b).height(),d=a(b).scrollTop()>this.$slot.height()+this.$slot.offset().top;return!c&&!d},f.prototype.prev=function(){return this.futureActive=this.getPrev(),this.isRunning=!0,this.stop(!1),this.futureActive},f.prototype.next=function(){return this.futureActive=this.getNext(),this.isRunning=!0,this.stop(!1),this.futureActive},f.prototype.shuffle=function(a,b){var c=this;b!==d&&(this._oncompleteStack[1]=b),this.isRunning=!0;var e=this.settings.delay;if(null===this.futureActive){var f=this.getCustom();this.futureActive=f}if("number"==typeof a)switch(a){case 1:case 2:this._setAnimationFX(l,!0);break;case 3:case 4:this._setAnimationFX(k,!0),e/=1.5;break;default:this._setAnimationFX(j,!0),e/=2}else this._setAnimationFX(j,!0),e/=2;return this.isVisible()||this.settings.stopHidden!==!0?this.$container.animate({marginTop:this._maxTop},e,"linear",function(){c.$container.css("margin-top",0),0>=a-1?c.stop():c.shuffle(a-1)}):(a=0,c.stop()),this.futureActive},f.prototype.stop=function(a){if(this.isRunning){if(this.isStopping)return this.futureActive;var b=this;this.$container.clearQueue().stop(!0,!1),this._setAnimationFX(l,a===d?!0:a),this.isRunning=!0,this.isStopping=!0,this.active=this.getVisibleTile(),this.futureActive>this.active?0===this.active&&this.futureActive===this.$tiles.length-1&&this.$container.css("margin-top",this.getTileOffset(this.$tiles.length)):this.active===this.$tiles.length-1&&0===this.futureActive&&this.$container.css("margin-top",0),this.active=this.futureActive;var c=3*this.settings.delay;return this.$container.animate({marginTop:this.getTileOffset(this.active)},c,"easeOutBounce",function(){b.isStopping=!1,b.isRunning=!1,b.futureActive=null,"function"==typeof b._oncompleteStack[0]&&b._oncompleteStack[0].apply(b,[b.active]),"function"==typeof b._oncompleteStack[1]&&b._oncompleteStack[1].apply(b,[b.active])}),setTimeout(function(){b._setAnimationFX(n,!1)},c/1.75),this.active}},f.prototype.auto=function(){var a=this;this._timer=new e(function(){"function"!=typeof a.settings.randomize&&(a.futureActive=a.getNext()),a.isRunning=!0,a.isVisible()||a.settings.stopHidden!==!0?a.shuffle(5,function(){a._timer.reset()}):setTimeout(function(){a._timer.reset()},500)},this.settings.auto)},a.fn[h]=function(b){return 1===this.length?g(this,b):this.each(function(){a.data(this,"plugin_"+h)||g(this,b)})}}(jQuery,window,document);
\ No newline at end of file
+!function(a,b,c,d){function e(a,b){var c,d,e=this,f=a,g=arguments,h=b;this.running=!1,this.onpause=function(){},this.onresume=function(){},this.cancel=function(){this.running=!1,clearTimeout(d)},this.pause=function(){this.running&&(b-=(new Date).getTime()-c,this.cancel(),this.onpause())},this.resume=function(){this.running||(this.running=!0,c=(new Date).getTime(),d=setTimeout(function(){f.apply(e,Array.prototype.slice.call(g,2,g.length))},b),this.onresume())},this.reset=function(){this.cancel(),this.running=!0,b=h,d=setTimeout(function(){f.apply(e,Array.prototype.slice.call(g,2,g.length))},h)},this.add=function(a){this.pause(),b+=a,this.resume()},this.resume()}function f(b,c){this.element=b,this.settings=a.extend({},i,c),this.defaults=i,this.name=h,this.$slot=a(b),this.$tiles=this.$slot.children(),this.$container=null,this._minTop=null,this._maxTop=null,this._$fakeFirstTile=null,this._$fakeLastTile=null,this._timer=null,this._oncompleteStack=[this.settings.complete],this._spinsLeft=null,this.futureActive=null,this.isRunning=!1,this.isStopping=!1,this.active=this.settings.active,this.$slot.css("overflow","hidden"),(this.settings.active<0||this.settings.active>=this.$tiles.length)&&(this.settings.active=0,this.active=0),this.$container=this.$tiles.wrapAll('').parent(),this._maxTop=-this.$container.height(),this._$fakeFirstTile=this.$tiles.last().clone(),this._$fakeLastTile=this.$tiles.first().clone(),this.$container.prepend(this._$fakeFirstTile),this.$container.append(this._$fakeLastTile),this._minTop=-this._$fakeFirstTile.outerHeight(),this.$container.css("margin-top",this.getTileOffset(this.active)),this.settings.auto!==!1&&(this.settings.auto===!0?this.shuffle():this.auto())}function g(b,c){var d;return a.data(b[0],"plugin_"+h)?d=a.data(b[0],"plugin_"+h):(d=new f(b,c),a.data(b[0],"plugin_"+h,d)),d}var h="slotMachine",i={active:0,delay:200,auto:!1,spins:5,randomize:null,complete:null,stopHidden:!0},j="slotMachineBlurFast",k="slotMachineBlurMedium",l="slotMachineBlurSlow",m="slotMachineGradient",n=m;a(c).ready(function(){var b='#slotMachineBlurFilterFast',c='#slotMachineBlurFilterMedium',d='#slotMachineBlurFilterSlow',e='#slotMachineFadeMask';a("body").append("')}),"function"!=typeof a.easing.easeOutBounce&&a.extend(a.easing,{easeOutBounce:function(a,b,c,d,e){return(b/=e)<1/2.75?7.5625*d*b*b+c:2/2.75>b?d*(7.5625*(b-=1.5/2.75)*b+.75)+c:2.5/2.75>b?d*(7.5625*(b-=2.25/2.75)*b+.9375)+c:d*(7.5625*(b-=2.625/2.75)*b+.984375)+c}}),f.prototype.getTileOffset=function(a){for(var b=0,c=0;a>c;c++)b+=this.$tiles.eq(c).outerHeight();return-b+this._minTop},f.prototype.getVisibleTile=function(){var a=this.$tiles.first().height(),b=parseInt(this.$container.css("margin-top").replace(/px/,""),10);return Math.abs(Math.round(b/a))-1},f.prototype.setRandomize=function(a){this.settings.randomize="number"==typeof a?function(){return a}:a},f.prototype.getRandom=function(a){var b,c=a||!1;do b=Math.floor(Math.random()*this.$tiles.length);while(c&&b===this.active&&b>=0);return b},f.prototype.getCustom=function(){var a;if(null!==this.settings.randomize&&"function"==typeof this.settings.randomize){var b=this.settings.randomize.apply(this,[this.active]);(0>b||b>=this.$tiles.length)&&(b=0),a=b}else a=this.getRandom();return a},f.prototype.getPrev=function(){var a=this.active-1<0?this.$tiles.length-1:this.active-1;return a},f.prototype.getNext=function(){var a=this.active+1a(b).scrollTop()+a(b).height(),d=a(b).scrollTop()>this.$slot.height()+this.$slot.offset().top;return!c&&!d},f.prototype.prev=function(){return this.futureActive=this.getPrev(),this.isRunning=!0,this.stop(!1),this.futureActive},f.prototype.next=function(){return this.futureActive=this.getNext(),this.isRunning=!0,this.stop(!1),this.futureActive},f.prototype.shuffle=function(a,b){var c=this;b!==d&&(this._oncompleteStack[1]=b),this.isRunning=!0;var e=this.settings.delay;if(null===this.futureActive){var f=this.getCustom();this.futureActive=f}if("number"==typeof a)switch(a){case 1:case 2:this._setAnimationFX(l,!0);break;case 3:case 4:this._setAnimationFX(k,!0),e/=1.5;break;default:this._setAnimationFX(j,!0),e/=2}else this._setAnimationFX(j,!0),e/=2;return this.isVisible()||this.settings.stopHidden!==!0?this.$container.animate({marginTop:this._maxTop},e,"linear",function(){c.$container.css("margin-top",0),0>=a-1?c.stop():c.shuffle(a-1)}):(a=0,c.stop()),this.futureActive},f.prototype.stop=function(a){if(this.isRunning){if(this.isStopping)return this.futureActive;var b=this;this.$container.clearQueue().stop(!0,!1),this._setAnimationFX(l,a===d?!0:a),this.isRunning=!0,this.isStopping=!0,this.active=this.getVisibleTile(),this.futureActive>this.active?0===this.active&&this.futureActive===this.$tiles.length-1&&this.$container.css("margin-top",this.getTileOffset(this.$tiles.length)):this.active===this.$tiles.length-1&&0===this.futureActive&&this.$container.css("margin-top",0),this.active=this.futureActive;var c=3*this.settings.delay;return this.$container.animate({marginTop:this.getTileOffset(this.active)},c,"easeOutBounce",function(){b.isStopping=!1,b.isRunning=!1,b.futureActive=null,"function"==typeof b._oncompleteStack[0]&&b._oncompleteStack[0].apply(b,[b.active]),"function"==typeof b._oncompleteStack[1]&&b._oncompleteStack[1].apply(b,[b.active])}),setTimeout(function(){b._setAnimationFX(n,!1)},c/1.75),this.active}},f.prototype.auto=function(){var a=this;this._timer=new e(function(){"function"!=typeof a.settings.randomize&&(a.futureActive=a.getNext()),a.isRunning=!0,a.isVisible()||a.settings.stopHidden!==!0?a.shuffle(a.settings.spins,function(){a._timer.reset()}):setTimeout(function(){a._timer.reset()},500)},this.settings.auto)},a.fn[h]=function(b){if(1===this.length)return g(this,b);var c=this;return a.map(c,function(a,d){var e=c.eq(d);return g(e,b)})}}(jQuery,window,document);
\ No newline at end of file
diff --git a/src/jquery.slotmachine.js b/src/jquery.slotmachine.js
index 6e83fb7..881a207 100644
--- a/src/jquery.slotmachine.js
+++ b/src/jquery.slotmachine.js
@@ -556,10 +556,10 @@
if (this.length === 1) {
return _getInstance(this, options);
} else {
- return this.each(function() {
- if (!$.data(this, 'plugin_' + pluginName)) {
- _getInstance(this, options);
- }
+ var $els = this;
+ return $.map($els, function(el, index) {
+ var $el = $els.eq(index);
+ return _getInstance($el, options);
});
}
};