1(function (factory) { 2 if (typeof define === 'function' && define.amd) { 3 define(['jquery'], factory); 4 } else if (typeof exports === 'object') { 5 module.exports = factory(require('jquery')); 6 } else { 7 factory(jQuery); 8 } 9})(function ($) { 10 var pluginName = 'tinycarousel', 11 defaults = { 12 start: 0, 13 axis: 'x', 14 buttons: true, 15 bullets: false, 16 interval: false, 17 intervalTime: 3000, 18 animation: true, 19 animationTime: 1000, 20 infinite: true, 21 }; 22 function Plugin($container, options) { 23 /** 24 * The options of the carousel extend with the defaults. 25 * 26 * @property options 27 * @type Object 28 * @default defaults 29 */ 30 this.options = $.extend({}, defaults, options); 31 32 /** 33 * @property _defaults 34 * @type Object 35 * @private 36 * @default defaults 37 */ 38 this._defaults = defaults; 39 40 /** 41 * @property _name 42 * @type String 43 * @private 44 * @final 45 * @default 'tinycarousel' 46 */ 47 this._name = pluginName; 48 49 var self = this, 50 $viewport = $container.find('.viewport:first'), 51 $overview = $container.find('.overview:first'), 52 $slides = null, 53 $next = $container.find('.next:first'), 54 $prev = $container.find('.prev:first'), 55 $bullets = $container.find('.bullet'), 56 viewportSize = 0, 57 contentStyle = {}, 58 slidesVisible = 0, 59 slideSize = 0, 60 slideIndex = 0, 61 isHorizontal = this.options.axis === 'x', 62 sizeLabel = isHorizontal ? 'Width' : 'Height', 63 posiLabel = isHorizontal ? 'left' : 'top', 64 intervalTimer = null; 65 /** 66 * The index of the current slide. 67 * 68 * @property slideCurrent 69 * @type Number 70 * @default 0 71 */ 72 this.slideCurrent = 0; 73 74 /** 75 * The number of slides the carousel is currently aware of. 76 * 77 * @property slidesTotal 78 * @type Number 79 * @default 0 80 */ 81 this.slidesTotal = 0; 82 83 /** 84 * If the interval is running the value will be true. 85 * 86 * @property intervalActive 87 * @type Boolean 88 * @default false 89 */ 90 this.intervalActive = false; 91 92 /** 93 * @method _initialize 94 * @private 95 */ 96 function _initialize() { 97 self.update(); 98 self.move(self.slideCurrent); 99 100 _setEvents(); 101 102 return self; 103 } 104 105 /** 106 * You can use this method to add new slides on the fly. Or to let the carousel recalculate itself. 107 * 108 * @method update 109 * @chainable 110 */ 111 this.update = function () { 112 $overview.find('.mirrored').remove(); 113 114 $slides = $overview.children(); 115 viewportSize = $viewport[0]['offset' + sizeLabel]; 116 slideSize = $slides.first()['outer' + sizeLabel](true); 117 self.slidesTotal = $slides.length; 118 self.slideCurrent = self.options.start || 0; 119 slidesVisible = Math.ceil(viewportSize / slideSize); 120 121 $overview.append( 122 $slides.slice(0, slidesVisible).clone().addClass('mirrored') 123 ); 124 $overview.css( 125 sizeLabel.toLowerCase(), 126 slideSize * (self.slidesTotal + slidesVisible) 127 ); 128 129 _setButtons(); 130 131 return self; 132 }; 133 134 /** 135 * @method _setEvents 136 * @private 137 */ 138 function _setEvents() { 139 if (self.options.buttons) { 140 $prev.click(function () { 141 self.move(--slideIndex); 142 143 return false; 144 }); 145 146 $next.click(function () { 147 self.move(++slideIndex); 148 149 return false; 150 }); 151 } 152 153 $(window).resize(self.update); 154 155 if (self.options.bullets) { 156 $container.on('click', '.bullet', function () { 157 self.move((slideIndex = +$(this).attr('data-slide'))); 158 159 return false; 160 }); 161 } 162 } 163 164 /** 165 * If the interval is stoped start it. 166 * 167 * @method start 168 * @chainable 169 */ 170 this.start = function () { 171 if (self.options.interval) { 172 clearTimeout(intervalTimer); 173 174 self.intervalActive = true; 175 176 intervalTimer = setTimeout(function () { 177 self.move(++slideIndex); 178 }, self.options.intervalTime); 179 } 180 181 return self; 182 }; 183 184 /** 185 * If the interval is running stop it. 186 * 187 * @method start 188 * @chainable 189 */ 190 this.stop = function () { 191 clearTimeout(intervalTimer); 192 193 self.intervalActive = false;
194 195 return self; 196 }; 197 198 /** 199 * Move to a specific slide. 200 * 201 * @method move 202 * @chainable 203 * @param {Number} [index] The slide to move to. 204 */ 205 this.move = function (index) { 206 slideIndex = isNaN(index) ? self.slideCurrent : index; 207 self.slideCurrent = slideIndex % self.slidesTotal; 208 209 if (slideIndex < 0) { 210 self.slideCurrent = slideIndex = self.slidesTotal - 1; 211 $overview.css(posiLabel, -self.slidesTotal * slideSize); 212 } 213 214 if (slideIndex > self.slidesTotal) { 215 self.slideCurrent = slideIndex = 1; 216 $overview.css(posiLabel, 0); 217 } 218 contentStyle[posiLabel] = -slideIndex * slideSize; 219 220 $overview.animate(contentStyle, { 221 queue: false, 222 duration: self.options.animation ? self.options.animationTime : 0, 223 always: function () { 224 /** 225 * The move event will trigger when the carousel slides to a new slide. 226 * 227 * @event move 228 */ 229 $container.trigger('move', [ 230 $slides[self.slideCurrent], 231 self.slideCurrent, 232 ]); 233 }, 234 }); 235 236 _setButtons(); 237 self.start(); 238 239 return self; 240 }; 241 242 /** 243 * @method _setButtons 244 * @private 245 */ 246 function _setButtons() { 247 if (self.options.buttons && !self.options.infinite) { 248 $prev.toggleClass('disable', self.slideCurrent <= 0); 249 $next.toggleClass( 250 'disable', 251 self.slideCurrent >= self.slidesTotal - slidesVisible 252 ); 253 } 254 255 if (self.options.bullets) { 256 $bullets.removeClass('active'); 257 $($bullets[self.slideCurrent]).addClass('active'); 258 } 259 } 260 261 return _initialize(); 262 } 263 264 /** 265 * @class tinycarousel 266 * @constructor 267 * @param {Object} options 268 @param {Number} [options.start=0] The slide to start with. 269 @param {String} [options.axis=x] Vertical or horizontal scroller? ( x || y ). 270 @param {Boolean} [options.buttons=true] Show previous and next navigation buttons. 271 @param {Boolean} [options.bullets=false] Is there a page number navigation present? 272 @param {Boolean} [options.interval=false] Move to another block on intervals. 273 @param {Number} [options.intervalTime=3000] Interval time in milliseconds. 274 @param {Boolean} [options.animate=true] False is instant, true is animate. 275 @param {Number} [options.animationTime=1000] How fast must the animation move in ms? 276 @param {Boolean} [options.infinite=true] Infinite carousel. 277 */ 278 $.fn[pluginName] = function (options) { 279 return this.each(function () { 280 if (!$.data(this, 'plugin_' + pluginName)) { 281 $.data(this, 'plugin_' + pluginName, new Plugin($(this), options)); 282 } 283 }); 284 }; 285});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.