diff --git a/lib/jquery.tinycarousel.js b/lib/jquery.tinycarousel.js index ef9c966..8ba4245 100644 --- a/lib/jquery.tinycarousel.js +++ b/lib/jquery.tinycarousel.js @@ -1,107 +1,158 @@ -;(function (factory) -{ - if (typeof define === 'function' && define.amd) - { +;(function(factory) { + if(typeof define === 'function' && define.amd) { define(['jquery'], factory); } - else if (typeof exports === 'object') - { - factory(require('jquery')); + else if(typeof exports === 'object') { + module.exports = factory(require('jquery')); } - else - { + else { factory(jQuery); } } -(function ($) -{ +(function($) { var pluginName = "tinycarousel" , defaults = { - start: 0 // The starting slide - , axis: "x" // vertical or horizontal scroller? ( x || y ). - , buttons: true // show left and right navigation buttons. - , bullets: false // is there a page number navigation present? - , interval: false // move to another block on intervals. - , intervalTime: 3000 // interval time in milliseconds. - , animation: true // false is instant, true is animate. - , animationTime: 1000 // how fast must the animation move in ms? - , infinite: true // infinite carousel. + start: 0 + , axis: "x" + , buttons: true + , bullets: false + , interval: false + , intervalTime: 3000 + , animation: true + , animationTime: 1000 + , infinite: true + , moveNumber: 1 } ; - function Plugin($container, options) - { - this.options = $.extend({}, defaults, options); + function Plugin($container, options) { + /** + * The options of the carousel extend with the defaults. + * + * @property options + * @type Object + * @default defaults + */ + this.options = $.extend({}, defaults, options); + + /** + * @property _defaults + * @type Object + * @private + * @default defaults + */ this._defaults = defaults; - this._name = pluginName; - var self = this + /** + * @property _name + * @type String + * @private + * @final + * @default 'tinycarousel' + */ + this._name = pluginName; + + var self = this , $viewport = $container.find(".viewport:first") , $overview = $container.find(".overview:first") - , $slides = 0 - , $next = $container.find(".next:first") - , $prev = $container.find(".prev:first") - , $bullets = $container.find(".bullet") - - , viewportSize = 0 - , contentStyle = {} - , slidesVisible = 0 - , slideSize = 0 - , slideIndex = 0 - - , isHorizontal = this.options.axis === 'x' - , sizeLabel = isHorizontal ? "Width" : "Height" - , posiLabel = isHorizontal ? "left" : "top" + , $slides = null + , $next = $container.find(".next:first") + , $prev = $container.find(".prev:first") + , $bullets = $container.find(".bullet") + + , viewportSize = 0 + , contentStyle = {} + , slidesVisible = 0 + , slideSize = 0 + , slideIndex = 0 + + , isHorizontal = this.options.axis === 'x' + , sizeLabel = isHorizontal ? "Width" : "Height" + , posiLabel = isHorizontal ? "left" : "top" , intervalTimer = null ; + /** + * The index of the current slide. + * + * @property slideCurrent + * @type Number + * @default 0 + */ this.slideCurrent = 0; - this.slidesTotal = 0; - function initialize() - { + /** + * The number of slides the carousel is currently aware of. + * + * @property slidesTotal + * @type Number + * @default 0 + */ + this.slidesTotal = 0; + + /** + * If the interval is running the value will be true. + * + * @property intervalActive + * @type Boolean + * @default false + */ + this.intervalActive = false; + + /** + * @method _initialize + * @private + */ + function _initialize() { self.update(); self.move(self.slideCurrent); - setEvents(); + _setEvents(); return self; } - this.update = function() - { + /** + * You can use this method to add new slides on the fly. Or to let the carousel recalculate itself. + * + * @method update + * @chainable + */ + this.update = function() { $overview.find(".mirrored").remove(); - $slides = $overview.children(); - viewportSize = $viewport[0]["offset" + sizeLabel]; - slideSize = $slides.first()["outer" + sizeLabel](true); - self.slidesTotal = $slides.length; + $slides = $overview.children(); + viewportSize = $viewport[0]["offset" + sizeLabel]; + slideSize = $slides.first()["outer" + sizeLabel](true); + self.slidesTotal = $slides.length; self.slideCurrent = self.options.start || 0; - slidesVisible = Math.ceil(viewportSize / slideSize); + slidesVisible = Math.ceil(viewportSize / slideSize); + self.moveNumber = (self.options.moveNumber > self.slidesTotal) ? self.slidesTotal : self.options.moveNumber; - $overview.append($slides.slice(0, slidesVisible).clone().addClass("mirrored")); - $overview.css(sizeLabel.toLowerCase(), slideSize * (self.slidesTotal + slidesVisible)); + $overview.append($slides.slice(0, self.slidesTotal).clone().addClass("mirrored")); + $overview.append($slides.slice(0, self.slidesTotal).clone().addClass("mirrored")); + $overview.css(sizeLabel.toLowerCase(), slideSize * self.slidesTotal * 3); - setButtons(); + _setButtons(); return self; }; - function setEvents() - { - if(self.options.buttons) - { - $prev.click(function() - { - self.move(--slideIndex); + /** + * @method _setEvents + * @private + */ + function _setEvents() { + if(self.options.buttons) { + $prev.click(function() { + self.move(slideIndex - self.moveNumber); return false; }); - $next.click(function() - { - self.move(++slideIndex); + $next.click(function() { + self.move(slideIndex + self.moveNumber); return false; }); @@ -109,10 +160,8 @@ $(window).resize(self.update); - if(self.options.bullets) - { - $container.on("click", ".bullet", function() - { + if(self.options.bullets) { + $container.on("click", ".bullet", function() { self.move(slideIndex = +$(this).attr("data-slide")); return false; @@ -120,15 +169,21 @@ } } - this.start = function() - { - if(self.options.interval) - { + + /** + * If the interval is stoped start it. + * + * @method start + * @chainable + */ + this.start = function() { + if(self.options.interval) { clearTimeout(intervalTimer); - intervalTimer = setTimeout(function() - { - self.move(++slideIndex); + self.intervalActive = true; + + intervalTimer = setTimeout(function() { + self.move(slideIndex + self.moveNumber); }, self.options.intervalTime); } @@ -136,75 +191,101 @@ return self; }; - this.stop = function() - { + /** + * If the interval is running stop it. + * + * @method start + * @chainable + */ + this.stop = function() { clearTimeout(intervalTimer); + self.intervalActive = false; + return self; }; - this.move = function(index) - { - slideIndex = index; + /** + * Move to a specific slide. + * + * @method move + * @chainable + * @param {Number} [index] The slide to move to. + */ + this.move = function(index) { + slideIndex = isNaN(index) ? self.slideCurrent : index; self.slideCurrent = slideIndex % self.slidesTotal; - if(slideIndex < 0) - { - self.slideCurrent = slideIndex = self.slidesTotal - 1; - $overview.css(posiLabel, -(self.slidesTotal) * slideSize); + if(slideIndex < 0) { + self.slideCurrent = slideIndex = index + self.slidesTotal; + $overview.css(posiLabel, -(slideIndex + self.moveNumber) * slideSize); } - if(slideIndex > self.slidesTotal) - { - self.slideCurrent = slideIndex = 1; - $overview.css(posiLabel, 0); + if(slideIndex > (self.slidesTotal*2)) { + self.slideCurrent = slideIndex = index - self.slidesTotal; + $overview.css(posiLabel, -(slideIndex - self.moveNumber) * slideSize); } - contentStyle[posiLabel] = -slideIndex * slideSize; $overview.animate( contentStyle , { - queue : false + queue : false , duration : self.options.animation ? self.options.animationTime : 0 - , always : function() - { + , always : function() { + /** + * The move event will trigger when the carousel slides to a new slide. + * + * @event move + */ $container.trigger("move", [$slides[self.slideCurrent], self.slideCurrent]); } - }); + }); - setButtons(); + _setButtons(); self.start(); return self; }; - function setButtons() - { - if(self.options.buttons && !self.options.infinite) - { + /** + * @method _setButtons + * @private + */ + function _setButtons() { + if(self.options.buttons && !self.options.infinite) { $prev.toggleClass("disable", self.slideCurrent <= 0); $next.toggleClass("disable", self.slideCurrent >= self.slidesTotal - slidesVisible); } - if(self.options.bullets) - { + if(self.options.bullets) { $bullets.removeClass("active"); $($bullets[self.slideCurrent]).addClass("active"); } } - return initialize(); + return _initialize(); } - $.fn[pluginName] = function(options) - { - return this.each(function() - { - if(!$.data(this, "plugin_" + pluginName)) - { + /** + * @class tinycarousel + * @constructor + * @param {Object} options + @param {Number} [options.start=0] The slide to start with. + @param {String} [options.axis=x] Vertical or horizontal scroller? ( x || y ). + @param {Boolean} [options.buttons=true] Show previous and next navigation buttons. + @param {Boolean} [options.bullets=false] Is there a page number navigation present? + @param {Boolean} [options.interval=false] Move to another block on intervals. + @param {Number} [options.intervalTime=3000] Interval time in milliseconds. + @param {Boolean} [options.animate=true] False is instant, true is animate. + @param {Number} [options.animationTime=1000] How fast must the animation move in ms? + @param {Boolean} [options.infinite=true] Infinite carousel. + */ + $.fn[pluginName] = function(options) { + return this.each(function() { + if(!$.data(this, "plugin_" + pluginName)) { $.data(this, "plugin_" + pluginName, new Plugin($(this), options)); } }); }; -})); \ No newline at end of file +})); diff --git a/lib/jquery.tinycarousel.min.js b/lib/jquery.tinycarousel.min.js index b2278d8..baa91fc 100644 --- a/lib/jquery.tinycarousel.min.js +++ b/lib/jquery.tinycarousel.min.js @@ -1,7 +1,7 @@ -/*! tinycarousel - v2.1.7 - 2014-12-01 +/*! tinycarousel - v2.1.7 - 2015-03-18 * https://baijs.com/tinycarousel * - * Copyright (c) 2014 Maarten Baijs ; + * Copyright (c) 2015 Maarten Baijs ; * Licensed under the MIT license */ -!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):a("object"==typeof exports?require("jquery"):jQuery)}(function(a){function b(b,e){function f(){return i.update(),i.move(i.slideCurrent),g(),i}function g(){i.options.buttons&&(n.click(function(){return i.move(--t),!1}),m.click(function(){return i.move(++t),!1})),a(window).resize(i.update),i.options.bullets&&b.on("click",".bullet",function(){return i.move(t=+a(this).attr("data-slide")),!1})}function h(){i.options.buttons&&!i.options.infinite&&(n.toggleClass("disable",i.slideCurrent<=0),m.toggleClass("disable",i.slideCurrent>=i.slidesTotal-r)),i.options.bullets&&(o.removeClass("active"),a(o[i.slideCurrent]).addClass("active"))}this.options=a.extend({},d,e),this._defaults=d,this._name=c;var i=this,j=b.find(".viewport:first"),k=b.find(".overview:first"),l=0,m=b.find(".next:first"),n=b.find(".prev:first"),o=b.find(".bullet"),p=0,q={},r=0,s=0,t=0,u="x"===this.options.axis,v=u?"Width":"Height",w=u?"left":"top",x=null;return this.slideCurrent=0,this.slidesTotal=0,this.update=function(){return k.find(".mirrored").remove(),l=k.children(),p=j[0]["offset"+v],s=l.first()["outer"+v](!0),i.slidesTotal=l.length,i.slideCurrent=i.options.start||0,r=Math.ceil(p/s),k.append(l.slice(0,r).clone().addClass("mirrored")),k.css(v.toLowerCase(),s*(i.slidesTotal+r)),h(),i},this.start=function(){return i.options.interval&&(clearTimeout(x),x=setTimeout(function(){i.move(++t)},i.options.intervalTime)),i},this.stop=function(){return clearTimeout(x),i},this.move=function(a){return t=a,i.slideCurrent=t%i.slidesTotal,0>t&&(i.slideCurrent=t=i.slidesTotal-1,k.css(w,-i.slidesTotal*s)),t>i.slidesTotal&&(i.slideCurrent=t=1,k.css(w,0)),q[w]=-t*s,k.animate(q,{queue:!1,duration:i.options.animation?i.options.animationTime:0,always:function(){b.trigger("move",[l[i.slideCurrent],i.slideCurrent])}}),h(),i.start(),i},f()}var c="tinycarousel",d={start:0,axis:"x",buttons:!0,bullets:!1,interval:!1,intervalTime:3e3,animation:!0,animationTime:1e3,infinite:!0};a.fn[c]=function(d){return this.each(function(){a.data(this,"plugin_"+c)||a.data(this,"plugin_"+c,new b(a(this),d))})}}); \ No newline at end of file +!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):"object"==typeof exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){function b(b,e){function f(){return i.update(),i.move(i.slideCurrent),g(),i}function g(){i.options.buttons&&(n.click(function(){return i.move(t-i.moveNumber),!1}),m.click(function(){return i.move(t+i.moveNumber),!1})),a(window).resize(i.update),i.options.bullets&&b.on("click",".bullet",function(){return i.move(t=+a(this).attr("data-slide")),!1})}function h(){i.options.buttons&&!i.options.infinite&&(n.toggleClass("disable",i.slideCurrent<=0),m.toggleClass("disable",i.slideCurrent>=i.slidesTotal-r)),i.options.bullets&&(o.removeClass("active"),a(o[i.slideCurrent]).addClass("active"))}this.options=a.extend({},d,e),this._defaults=d,this._name=c;var i=this,j=b.find(".viewport:first"),k=b.find(".overview:first"),l=null,m=b.find(".next:first"),n=b.find(".prev:first"),o=b.find(".bullet"),p=0,q={},r=0,s=0,t=0,u="x"===this.options.axis,v=u?"Width":"Height",w=u?"left":"top",x=null;return this.slideCurrent=0,this.slidesTotal=0,this.intervalActive=!1,this.update=function(){return k.find(".mirrored").remove(),l=k.children(),p=j[0]["offset"+v],s=l.first()["outer"+v](!0),i.slidesTotal=l.length,i.slideCurrent=i.options.start||0,r=Math.ceil(p/s),i.moveNumber=i.options.moveNumber>i.slidesTotal?i.slidesTotal:i.options.moveNumber,k.append(l.slice(0,i.slidesTotal).clone().addClass("mirrored")),k.append(l.slice(0,i.slidesTotal).clone().addClass("mirrored")),k.css(v.toLowerCase(),s*i.slidesTotal*3),h(),i},this.start=function(){return i.options.interval&&(clearTimeout(x),i.intervalActive=!0,x=setTimeout(function(){i.move(t+i.moveNumber)},i.options.intervalTime)),i},this.stop=function(){return clearTimeout(x),i.intervalActive=!1,i},this.move=function(a){return t=isNaN(a)?i.slideCurrent:a,i.slideCurrent=t%i.slidesTotal,0>t&&(i.slideCurrent=t=a+i.slidesTotal,k.css(w,-(t+i.moveNumber)*s)),t>2*i.slidesTotal&&(i.slideCurrent=t=a-i.slidesTotal,k.css(w,-(t-i.moveNumber)*s)),q[w]=-t*s,k.animate(q,{queue:!1,duration:i.options.animation?i.options.animationTime:0,always:function(){b.trigger("move",[l[i.slideCurrent],i.slideCurrent])}}),h(),i.start(),i},f()}var c="tinycarousel",d={start:0,axis:"x",buttons:!0,bullets:!1,interval:!1,intervalTime:3e3,animation:!0,animationTime:1e3,infinite:!0,moveNumber:1};a.fn[c]=function(d){return this.each(function(){a.data(this,"plugin_"+c)||a.data(this,"plugin_"+c,new b(a(this),d))})}}); \ No newline at end of file