spree_multi_slideshow 0.70.71 → 0.70.72

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -9,7 +9,7 @@ Basic Installation
9
9
 
10
10
  1. Add the following to your Gemfile
11
11
  <pre>
12
- gem 'spree_multi_slideshow', '~> 0.70.6'
12
+ gem 'spree_multi_slideshow', '~> 0.70.72'
13
13
  </pre>
14
14
  2. Run `bundle install`
15
15
  3. To copy and apply migrations run:
@@ -1,231 +1,1177 @@
1
- //= require store/spree_core
1
+ /**
2
+ * BxSlider v4.0 - Fully loaded, responsive content slider
3
+ * http://bxslider.com
4
+ *
5
+ * Copyright 2012, Steven Wanderski - http://stevenwanderski.com - http://bxcreative.com
6
+ * Written while drinking Belgian ales and listening to jazz
7
+ *
8
+ * Released under the WTFPL license - http://sam.zoy.org/wtfpl/
9
+ */
2
10
 
3
- // page init
4
- jQuery(function($) {
5
- initGalleries();
6
- });
11
+ ;(function($){
7
12
 
8
- // galleries init
9
- function initGalleries(){
10
- // main banner slideshow
11
- jQuery('div.gallery').fadeGallery({
12
- autoRotation: true,
13
- switchTime: 5000, //ms
14
- duration: 800 //ms
15
- });
16
- };
13
+ var plugin = {};
14
+
15
+ var defaults = {
16
+
17
+ // GENERAL
18
+ mode: 'horizontal',
19
+ slideSelector: '',
20
+ infiniteLoop: true,
21
+ hideControlOnEnd: false,
22
+ speed: 500,
23
+ easing: null,
24
+ slideMargin: 0,
25
+ startSlide: 0,
26
+ randomStart: false,
27
+ captions: false,
28
+ ticker: false,
29
+ tickerHover: false,
30
+ adaptiveHeight: false,
31
+ adaptiveHeightSpeed: 500,
32
+ touchEnabled: true,
33
+ swipeThreshold: 50,
34
+ video: false,
35
+ useCSS: true,
36
+
37
+ // PAGER
38
+ pager: true,
39
+ pagerType: 'full',
40
+ pagerShortSeparator: ' / ',
41
+ pagerSelector: null,
42
+ buildPager: null,
43
+ pagerCustom: null,
44
+
45
+ // CONTROLS
46
+ controls: true,
47
+ nextText: 'Next',
48
+ prevText: 'Prev',
49
+ nextSelector: null,
50
+ prevSelector: null,
51
+ autoControls: false,
52
+ startText: 'Start',
53
+ stopText: 'Stop',
54
+ autoControlsCombine: false,
55
+ autoControlsSelector: null,
56
+
57
+ // AUTO
58
+ auto: false,
59
+ pause: 4000,
60
+ autoStart: true,
61
+ autoDirection: 'next',
62
+ autoHover: false,
63
+ autoDelay: 0,
64
+
65
+ // CAROUSEL
66
+ minSlides: 1,
67
+ maxSlides: 1,
68
+ moveSlides: 0,
69
+ slideWidth: 0,
70
+
71
+ // CALLBACKS
72
+ onSliderLoad: function() {},
73
+ onSlideBefore: function() {},
74
+ onSlideAfter: function() {},
75
+ onSlideNext: function() {},
76
+ onSlidePrev: function() {}
77
+ }
17
78
 
18
- // slideshow plugin
19
- jQuery.fn.fadeGallery = function(_options){
20
- var _options = jQuery.extend({
21
- slideElements:'div.frame > ul > li',
22
- pagerGener: false,
23
- pagerHold: false,
24
- pagerLinks:'ul.nav-list li',
25
- btnNext:'a.next',
26
- btnPrev:'a.prev',
27
- btnPlayPause:'a.play-pause',
28
- btnPlay:'a.play',
29
- btnPause:'a.pause',
30
- pausedClass:'paused',
31
- disabledClass: 'disabled',
32
- playClass:'playing',
33
- activeClass:'active',
34
- currentNum:false,
35
- allNum:false,
36
- startSlide:null,
37
- noCircle:false,
38
- caption:'ul.caption > li',
39
- pauseOnHover:false,
40
- autoRotation:false,
41
- autoHeight:false,
42
- onChange:false,
43
- switchTime:3000,
44
- duration:650,
45
- event:'click'
46
- },_options);
47
-
48
- return this.each(function(){
49
- // gallery options
50
- var _this = jQuery(this);
51
- var _slides = jQuery(_options.slideElements, _this);
52
- var _btnPrev = jQuery(_options.btnPrev, _this);
53
- var _btnNext = jQuery(_options.btnNext, _this);
54
- var _btnPlayPause = jQuery(_options.btnPlayPause, _this);
55
- var _btnPause = jQuery(_options.btnPause, _this);
56
- var _btnPlay = jQuery(_options.btnPlay, _this);
57
- var _pauseOnHover = _options.pauseOnHover;
58
- var _autoRotation = _options.autoRotation;
59
- var _activeClass = _options.activeClass;
60
- var _disabledClass = _options.disabledClass;
61
- var _pausedClass = _options.pausedClass;
62
- var _playClass = _options.playClass;
63
- var _autoHeight = _options.autoHeight;
64
- var _duration = _options.duration;
65
- var _switchTime = _options.switchTime;
66
- var _controlEvent = _options.event;
67
- var _currentNum = (_options.currentNum ? jQuery(_options.currentNum, _this) : false);
68
- var _allNum = (_options.allNum ? jQuery(_options.allNum, _this) : false);
69
- var _startSlide = _options.startSlide;
70
- var _noCycle = _options.noCircle;
71
- var _onChange = _options.onChange;
72
- var _pagerGener = _options.pagerGener;
73
- var _pagerHold = jQuery(_options.pagerHold,_this);
74
- var _caption = jQuery(_options.caption,_this);
75
- var _paging = '';
76
- if(_pagerGener){
77
- for(var i=0; i< _slides.length; i++){
78
- _paging += '<li><a href="#">'+(i+1)+'</a></li>';
79
- }
80
- _pagerHold.html('<ul>'+_paging+'</ul>');
81
- }
82
- var _pagerLinks = jQuery(_options.pagerLinks, _this);
83
- // gallery init
84
- var _hover = false;
85
- var _prevIndex = 0;
86
- var _currentIndex = 0;
87
- var _slideCount = _slides.length;
88
- var _timer;
89
- if(_slideCount < 2) return;
90
-
91
- _prevIndex = _slides.index(_slides.filter('.'+_activeClass));
92
- if(_prevIndex < 0) _prevIndex = _currentIndex = 0;
93
- else _currentIndex = _prevIndex;
94
- if(_startSlide != null) {
95
- if(_startSlide == 'random') _prevIndex = _currentIndex = Math.floor(Math.random()*_slideCount);
96
- else _prevIndex = _currentIndex = parseInt(_startSlide);
97
- }
98
- _slides.hide().eq(_currentIndex).show();
99
- _caption.hide().eq(_currentIndex).show();
100
- if(_autoRotation) _this.removeClass(_pausedClass).addClass(_playClass);
101
- else _this.removeClass(_playClass).addClass(_pausedClass);
102
-
103
- // gallery control
104
- if(_btnPrev.length) {
105
- _btnPrev.bind(_controlEvent,function(){
106
- prevSlide();
107
- return false;
108
- });
79
+ $.fn.bxSlider = function(options){
80
+
81
+ if(this.length == 0) return;
82
+
83
+ // support mutltiple elements
84
+ if(this.length > 1){
85
+ this.each(function(){$(this).bxSlider(options)});
86
+ return this;
109
87
  }
110
- if(_btnNext.length) {
111
- _btnNext.bind(_controlEvent,function(){
112
- nextSlide();
88
+
89
+ // create a namespace to be used throughout the plugin
90
+ var slider = {};
91
+ // set a reference to our slider element
92
+ var el = this;
93
+ plugin.el = this;
94
+
95
+ /**
96
+ * ===================================================================================
97
+ * = PRIVATE FUNCTIONS
98
+ * ===================================================================================
99
+ */
100
+
101
+ /**
102
+ * Initializes namespace settings to be used throughout plugin
103
+ */
104
+ var init = function(){
105
+ // merge user-supplied options with the defaults
106
+ slider.settings = $.extend({}, defaults, options);
107
+ // store the original children
108
+ slider.children = el.children(slider.settings.slideSelector);
109
+ // if random start, set the startSlide setting to random number
110
+ if(slider.settings.randomStart) slider.settings.startSlide = Math.floor(Math.random() * slider.children.length);
111
+ // store active slide information
112
+ slider.active = { index: slider.settings.startSlide }
113
+ // store if the slider is in carousel mode (displaying / moving multiple slides)
114
+ slider.carousel = slider.settings.minSlides > 1 || slider.settings.maxSlides > 1;
115
+ // calculate the min / max width thresholds based on min / max number of slides
116
+ // used to setup and update carousel slides dimensions
117
+ slider.minThreshold = (slider.settings.minSlides * slider.settings.slideWidth) + ((slider.settings.minSlides - 1) * slider.settings.slideMargin);
118
+ slider.maxThreshold = (slider.settings.maxSlides * slider.settings.slideWidth) + ((slider.settings.maxSlides - 1) * slider.settings.slideMargin);
119
+ // store the current state of the slider (if currently animating, working is true)
120
+ slider.working = false;
121
+ // initialize the controls object
122
+ slider.controls = {};
123
+ // determine which property to use for transitions
124
+ slider.animProp = slider.settings.mode == 'vertical' ? 'top' : 'left';
125
+ // determine if hardware acceleration can be used
126
+ slider.usingCSS = slider.settings.useCSS && slider.settings.mode != 'fade' && (function(){
127
+ // create our test div element
128
+ var div = document.createElement('div');
129
+ // css transition properties
130
+ var props = ['WebkitPerspective', 'MozPerspective', 'OPerspective', 'msPerspective'];
131
+ // test for each property
132
+ for(var i in props){
133
+ if(div.style[props[i]] !== undefined){
134
+ slider.cssPrefix = props[i].replace('Perspective', '').toLowerCase();
135
+ slider.animProp = '-' + slider.cssPrefix + '-transform';
136
+ return true;
137
+ }
138
+ }
113
139
  return false;
140
+ }());
141
+ // if vertical mode always make maxSlides and minSlides equal
142
+ if(slider.settings.mode == 'vertical') slider.settings.maxSlides = slider.settings.minSlides;
143
+ // perform all DOM / CSS modifications
144
+ setup();
145
+ }
146
+
147
+ /**
148
+ * Performs all DOM and CSS modifications
149
+ */
150
+ var setup = function(){
151
+ // wrap el in a wrapper
152
+ el.wrap('<div class="bx-wrapper"><div class="bx-viewport"></div></div>');
153
+ // store a namspace reference to .bx-viewport
154
+ slider.viewport = el.parent();
155
+ // add a loading div to display while images are loading
156
+ slider.loader = $('<div class="bx-loading" />');
157
+ slider.viewport.prepend(slider.loader);
158
+ // set el to a massive width, to hold any needed slides
159
+ // also strip any margin and padding from el
160
+ el.css({
161
+ width: slider.settings.mode == 'horizontal' ? slider.children.length * 215 + '%' : 'auto',
162
+ position: 'relative',
163
+ });
164
+ // if using CSS, add the easing property
165
+ if(slider.usingCSS && slider.settings.easing){
166
+ el.css('-' + slider.cssPrefix + '-transition-timing-function', slider.settings.easing);
167
+ // if not using CSS and no easing value was supplied, use the default JS animation easing (swing)
168
+ }else if(!slider.settings.easing){
169
+ slider.settings.easing = 'swing';
170
+ }
171
+ // make modifications to the viewport (.bx-viewport)
172
+ slider.viewport.css({
173
+ width: '100%',
174
+ overflow: 'hidden',
175
+ position: 'relative'
176
+ });
177
+ // apply css to all slider children
178
+ slider.children.css({
179
+ float: slider.settings.mode == 'horizontal' ? 'left' : 'none',
180
+ listStyle: 'none',
181
+ });
182
+ // apply the calculated width after the float is applied to prevent scrollbar interference
183
+ slider.children.width(getSlideWidth());
184
+ // if slideMargin is supplied, add the css
185
+ if(slider.settings.mode == 'horizontal' && slider.settings.slideMargin > 0) slider.children.css('marginRight', slider.settings.slideMargin);
186
+ if(slider.settings.mode == 'vertical' && slider.settings.slideMargin > 0) slider.children.css('marginBottom', slider.settings.slideMargin);
187
+ // if "fade" mode, add positioning and z-index CSS
188
+ if(slider.settings.mode == 'fade'){
189
+ slider.children.css({
190
+ position: 'absolute',
191
+ zIndex: 0,
192
+ display: 'none'
193
+ });
194
+ // prepare the z-index on the showing element
195
+ slider.children.eq(slider.settings.startSlide).css({zIndex: 50, display: 'block'});
196
+ }
197
+ // create an element to contain all slider controls (pager, start / stop, etc)
198
+ slider.controls.el = $('<div class="bx-controls" />');
199
+ // if captions are requested, add them
200
+ if(slider.settings.captions) appendCaptions();
201
+ // if infinite loop, prepare additional slides
202
+ if(slider.settings.infiniteLoop && slider.settings.mode != 'fade' && !slider.settings.ticker){
203
+ var slice = slider.settings.mode == 'vertical' ? slider.settings.minSlides : slider.settings.maxSlides;
204
+ var sliceAppend = slider.children.slice(0, slice).clone().addClass('bx-clone');
205
+ var slicePrepend = slider.children.slice(-slice).clone().addClass('bx-clone');
206
+ el.append(sliceAppend).prepend(slicePrepend);
207
+ }
208
+ // check if startSlide is last slide
209
+ slider.active.last = slider.settings.startSlide == getPagerQty() - 1;
210
+ // if video is true, set up the fitVids plugin
211
+ if(slider.settings.video) el.fitVids();
212
+ // only check for control addition if not in "ticker" mode
213
+ if(!slider.settings.ticker){
214
+ // if pager is requested, add it
215
+ if(slider.settings.pager) appendPager();
216
+ // if controls are requested, add them
217
+ if(slider.settings.controls) appendControls();
218
+ // if auto is true, and auto controls are requested, add them
219
+ if(slider.settings.auto && slider.settings.autoControls) appendControlsAuto();
220
+ // if any control option is requested, add the controls wrapper
221
+ if(slider.settings.controls || slider.settings.autoControls || slider.settings.pager) slider.viewport.after(slider.controls.el);
222
+ }
223
+ // preload all images, then perform final DOM / CSS modifications that depend on images being loaded
224
+ el.children().imagesLoaded(function(){
225
+ // remove the loading DOM element
226
+ slider.loader.remove();
227
+ // set the left / top position of "el"
228
+ setSlidePosition();
229
+ // if "vertical" mode, always use adaptiveHeight to prevent odd behavior
230
+ if (slider.settings.mode == 'vertical') slider.settings.adaptiveHeight = true;
231
+ // set the viewport height
232
+ slider.viewport.height(getViewportHeight());
233
+ // onSliderLoad callback
234
+ slider.settings.onSliderLoad(slider.active.index);
235
+ // if auto is true, start the show
236
+ if (slider.settings.auto && slider.settings.autoStart) initAuto();
237
+ // if ticker is true, start the ticker
238
+ if (slider.settings.ticker) initTicker();
239
+ // if pager is requested, make the appropriate pager link active
240
+ if (slider.settings.pager) updatePagerActive(slider.settings.startSlide);
241
+ // check for any updates to the controls (like hideControlOnEnd updates)
242
+ if (slider.settings.controls) updateDirectionControls();
243
+ // if touchEnabled is true, setup the touch events
244
+ if (slider.settings.touchEnabled && !slider.settings.ticker) initTouch();
114
245
  });
115
246
  }
116
- if(_pagerLinks.length) {
117
- _pagerLinks.each(function(_ind){
118
- jQuery(this).bind(_controlEvent,function(){
119
- if(_currentIndex != _ind) {
120
- _prevIndex = _currentIndex;
121
- _currentIndex = _ind;
122
- switchSlide();
247
+
248
+ /**
249
+ * Returns the calculated height of the viewport, used to determine either adaptiveHeight or the maxHeight value
250
+ */
251
+ var getViewportHeight = function(){
252
+ var height = 0;
253
+ // first determine which children (slides) should be used in our height calculation
254
+ var children = $();
255
+ // if mode is not "vertical", adaptiveHeight is always false, so return all children
256
+ if(slider.settings.mode != 'vertical' && !slider.settings.adaptiveHeight){
257
+ children = slider.children;
258
+ }else{
259
+ // if not carousel, return the single active child
260
+ if(!slider.carousel){
261
+ children = slider.children.eq(slider.active.index);
262
+ // if carousel, return a slice of children
263
+ }else{
264
+ // get the individual slide index
265
+ var currentIndex = slider.settings.moveSlides == 1 ? slider.active.index : slider.active.index * getMoveBy();
266
+ // add the current slide to the children
267
+ children = slider.children.eq(currentIndex);
268
+ // cycle through the remaining "showing" slides
269
+ for (i = 1; i <= slider.settings.maxSlides - 1; i++){
270
+ // if looped back to the start
271
+ if(currentIndex + i >= slider.children.length){
272
+ children = children.add(slider.children.eq(i - 1));
273
+ }else{
274
+ children = children.add(slider.children.eq(currentIndex + i));
275
+ }
123
276
  }
124
- return false;
277
+ }
278
+ }
279
+ // if "vertical" mode, calculate the sum of the heights of the children
280
+ if(slider.settings.mode == 'vertical'){
281
+ children.each(function(index) {
282
+ height += $(this).outerHeight();
125
283
  });
126
- });
284
+ // add user-supplied margins
285
+ if(slider.settings.slideMargin > 0){
286
+ height += slider.settings.slideMargin * (slider.settings.minSlides - 1);
287
+ }
288
+ // if not "vertical" mode, calculate the max height of the children
289
+ }else{
290
+ height = Math.max.apply(Math, children.map(function(){
291
+ return $(this).outerHeight(false);
292
+ }).get());
293
+ }
294
+ return height;
127
295
  }
128
-
129
- // play pause section
130
- if(_btnPlayPause.length) {
131
- _btnPlayPause.bind(_controlEvent,function(){
132
- if(_this.hasClass(_pausedClass)) {
133
- _this.removeClass(_pausedClass).addClass(_playClass);
134
- _autoRotation = true;
135
- autoSlide();
136
- } else {
137
- _autoRotation = false;
138
- if(_timer) clearTimeout(_timer);
139
- _this.removeClass(_playClass).addClass(_pausedClass);
296
+
297
+ /**
298
+ * Returns the calculated width to be applied to each slide
299
+ */
300
+ var getSlideWidth = function(){
301
+ // start with any user-supplied slide width
302
+ var newElWidth = slider.settings.slideWidth;
303
+ // get the current viewport width
304
+ var wrapWidth = slider.viewport.width();
305
+ // if slide width was not supplied, use the viewport width (means not carousel)
306
+ if(slider.settings.slideWidth == 0){
307
+ newElWidth = wrapWidth;
308
+ // if carousel, use the thresholds to determine the width
309
+ }else{
310
+ if(wrapWidth > slider.maxThreshold){
311
+ newElWidth = (wrapWidth - (slider.settings.slideMargin * (slider.settings.maxSlides - 1))) / slider.settings.maxSlides;
312
+ }else if(wrapWidth < slider.minThreshold){
313
+ newElWidth = (wrapWidth - (slider.settings.slideMargin * (slider.settings.minSlides - 1))) / slider.settings.minSlides;
140
314
  }
141
- return false;
142
- });
315
+ }
316
+ return newElWidth;
143
317
  }
144
- if(_btnPlay.length) {
145
- _btnPlay.bind(_controlEvent,function(){
146
- _this.removeClass(_pausedClass).addClass(_playClass);
147
- _autoRotation = true;
148
- autoSlide();
149
- return false;
150
- });
318
+
319
+ /**
320
+ * Returns the number of slides currently visible in the viewport (includes partially visible slides)
321
+ */
322
+ var getNumberSlidesShowing = function(){
323
+ var slidesShowing = 1;
324
+ if(slider.settings.mode == 'horizontal'){
325
+ // if viewport is smaller than minThreshold, return minSlides
326
+ if(slider.viewport.width() < slider.minThreshold){
327
+ slidesShowing = slider.settings.minSlides;
328
+ // if viewport is larger than minThreshold, return maxSlides
329
+ }else if(slider.viewport.width() > slider.maxThreshold){
330
+ slidesShowing = slider.settings.maxSlides;
331
+ // if viewport is between min / max thresholds, divide viewport width by first child width
332
+ }else{
333
+ var childWidth = slider.children.first().width();
334
+ slidesShowing = Math.floor(slider.viewport.width() / childWidth);
335
+ }
336
+ // if "vertical" mode, slides showing will always be minSlides
337
+ }else if(slider.settings.mode == 'vertical'){
338
+ slidesShowing = slider.settings.minSlides;
339
+ }
340
+ return slidesShowing;
151
341
  }
152
- if(_btnPause.length) {
153
- _btnPause.bind(_controlEvent,function(){
154
- _autoRotation = false;
155
- if(_timer) clearTimeout(_timer);
156
- _this.removeClass(_playClass).addClass(_pausedClass);
157
- return false;
342
+
343
+ /**
344
+ * Returns the number of pages (one full viewport of slides is one "page")
345
+ */
346
+ var getPagerQty = function(){
347
+ var pagerQty = 0;
348
+ // if moveSlides is specified by the user
349
+ if(slider.settings.moveSlides > 0){
350
+ if(slider.settings.infiniteLoop){
351
+ pagerQty = slider.children.length / getMoveBy();
352
+ }else{
353
+ // use a while loop to determine pages
354
+ var breakPoint = 0;
355
+ var counter = 0
356
+ // when breakpoint goes above children length, counter is the number of pages
357
+ while (breakPoint < slider.children.length){
358
+ ++pagerQty;
359
+ breakPoint = counter + getNumberSlidesShowing();
360
+ counter += slider.settings.moveSlides <= getNumberSlidesShowing() ? slider.settings.moveSlides : getNumberSlidesShowing();
361
+ }
362
+ }
363
+ // if moveSlides is 0 (auto) divide children length by sides showing, then round up
364
+ }else{
365
+ pagerQty = Math.ceil(slider.children.length / getNumberSlidesShowing());
366
+ }
367
+ return pagerQty;
368
+ }
369
+
370
+ /**
371
+ * Returns the number of indivual slides by which to shift the slider
372
+ */
373
+ var getMoveBy = function(){
374
+ // if moveSlides was set by the user and moveSlides is less than number of slides showing
375
+ if(slider.settings.moveSlides > 0 && slider.settings.moveSlides <= getNumberSlidesShowing()){
376
+ return slider.settings.moveSlides;
377
+ }
378
+ // if moveSlides is 0 (auto)
379
+ return getNumberSlidesShowing();
380
+ }
381
+
382
+ /**
383
+ * Sets the slider's (el) left or top position
384
+ */
385
+ var setSlidePosition = function(){
386
+ // if last slide
387
+ if(slider.active.last){
388
+ if (slider.settings.mode == 'horizontal'){
389
+ // get the last child's position
390
+ var lastChild = slider.children.last();
391
+ var position = lastChild.position();
392
+ // set the left position
393
+ setPositionProperty(-(position.left - (slider.viewport.width() - lastChild.width())), 'reset', 0);
394
+ }else if(slider.settings.mode == 'vertical'){
395
+ // get the last showing index's position
396
+ var lastShowingIndex = slider.children.length - slider.settings.minSlides;
397
+ var position = slider.children.eq(lastShowingIndex).position();
398
+ // set the top position
399
+ setPositionProperty(-position.top, 'reset', 0);
400
+ }
401
+ // if not last slide
402
+ }else{
403
+ // get the position of the first showing slide
404
+ var position = slider.children.eq(slider.active.index * getMoveBy()).position();
405
+ // check for last slide
406
+ if (slider.active.index == getPagerQty() - 1) slider.active.last = true;
407
+ // set the repective position
408
+ if (position != undefined){
409
+ if (slider.settings.mode == 'horizontal') setPositionProperty(-position.left, 'reset', 0);
410
+ else if (slider.settings.mode == 'vertical') setPositionProperty(-position.top, 'reset', 0);
411
+ }
412
+ }
413
+ }
414
+
415
+ /**
416
+ * Sets the el's animating property position (which in turn will sometimes animate el).
417
+ * If using CSS, sets the transform property. If not using CSS, sets the top / left property.
418
+ *
419
+ * @param value (int)
420
+ * - the animating property's value
421
+ *
422
+ * @param type (string) 'slider', 'reset', 'ticker'
423
+ * - the type of instance for which the function is being
424
+ *
425
+ * @param duration (int)
426
+ * - the amount of time (in ms) the transition should occupy
427
+ *
428
+ * @param params (array) optional
429
+ * - an optional parameter containing any variables that need to be passed in
430
+ */
431
+ var setPositionProperty = function(value, type, duration, params){
432
+ // use CSS transform
433
+ if(slider.usingCSS){
434
+ // determine the translate3d value
435
+ var propValue = slider.settings.mode == 'vertical' ? 'translate3d(0, ' + value + 'px, 0)' : 'translate3d(' + value + 'px, 0, 0)';
436
+ // add the CSS transition-duration
437
+ el.css('-' + slider.cssPrefix + '-transition-duration', duration / 1000 + 's');
438
+ if(type == 'slide'){
439
+ // set the property value
440
+ el.css(slider.animProp, propValue);
441
+ // bind a callback method - executes when CSS transition completes
442
+ el.bind('transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd', function(){
443
+ // unbind the callback
444
+ el.unbind('transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd');
445
+ updateAfterSlideTransition();
446
+ });
447
+ }else if(type == 'reset'){
448
+ el.css(slider.animProp, propValue);
449
+ }else if(type == 'ticker'){
450
+ // make the transition use 'linear'
451
+ el.css('-' + slider.cssPrefix + '-transition-timing-function', 'linear');
452
+ el.css(slider.animProp, propValue);
453
+ // bind a callback method - executes when CSS transition completes
454
+ el.bind('transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd', function(){
455
+ // unbind the callback
456
+ el.unbind('transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd');
457
+ // reset the position
458
+ setPositionProperty(params['resetValue'], 'reset', 0);
459
+ // start the loop again
460
+ tickerLoop();
461
+ });
462
+ }
463
+ // use JS animate
464
+ }else{
465
+ var animateObj = {};
466
+ animateObj[slider.animProp] = value;
467
+ if(type == 'slide'){
468
+ el.animate(animateObj, duration, slider.settings.easing, function(){
469
+ updateAfterSlideTransition();
470
+ });
471
+ }else if(type == 'reset'){
472
+ el.css(slider.animProp, value)
473
+ }else if(type == 'ticker'){
474
+ el.animate(animateObj, speed, 'linear', function(){
475
+ setPositionProperty(params['resetValue'], 'reset', 0);
476
+ // run the recursive loop after animation
477
+ tickerLoop();
478
+ });
479
+ }
480
+ }
481
+ }
482
+
483
+ /**
484
+ * Populates the pager with proper amount of pages
485
+ */
486
+ var populatePager = function(){
487
+ var pagerHtml = '';
488
+ pagerQty = getPagerQty();
489
+ // loop through each pager item
490
+ for(var i=0; i < pagerQty; i++){
491
+ var linkContent = '';
492
+ // if a buildPager function is supplied, use it to get pager link value, else use index + 1
493
+ if(slider.settings.buildPager && $.isFunction(slider.settings.buildPager)){
494
+ linkContent = slider.settings.buildPager(i);
495
+ slider.pagerEl.addClass('bx-custom-pager');
496
+ }else{
497
+ linkContent = i + 1;
498
+ slider.pagerEl.addClass('bx-default-pager');
499
+ }
500
+ // var linkContent = slider.settings.buildPager && $.isFunction(slider.settings.buildPager) ? slider.settings.buildPager(i) : i + 1;
501
+ // add the markup to the string
502
+ pagerHtml += '<div class="bx-pager-item"><a href="" data-slide-index="' + i + '" class="bx-pager-link">' + linkContent + '</a></div>';
503
+ };
504
+ // populate the pager element with pager links
505
+ slider.pagerEl.html(pagerHtml);
506
+ }
507
+
508
+ /**
509
+ * Appends the pager to the controls element
510
+ */
511
+ var appendPager = function(){
512
+ if(!slider.settings.pagerCustom){
513
+ // create the pager DOM element
514
+ slider.pagerEl = $('<div class="bx-pager" />');
515
+ // if a pager selector was supplied, populate it with the pager
516
+ if(slider.settings.pagerSelector){
517
+ $(slider.settings.pagerSelector).html(slider.pagerEl);
518
+ // if no pager selector was supplied, add it after the wrapper
519
+ }else{
520
+ slider.controls.el.addClass('bx-has-pager').append(slider.pagerEl);
521
+ }
522
+ // populate the pager
523
+ populatePager();
524
+ }else{
525
+ slider.pagerEl = $(slider.settings.pagerCustom);
526
+ }
527
+ // assign the pager click binding
528
+ slider.pagerEl.delegate('a', 'click', clickPagerBind);
529
+ }
530
+
531
+ /**
532
+ * Appends prev / next controls to the controls element
533
+ */
534
+ var appendControls = function(){
535
+ slider.controls.next = $('<a class="bx-next" href="">' + slider.settings.nextText + '</a>');
536
+ slider.controls.prev = $('<a class="bx-prev" href="">' + slider.settings.prevText + '</a>');
537
+ // bind click actions to the controls
538
+ slider.controls.next.bind('click', clickNextBind);
539
+ slider.controls.prev.bind('click', clickPrevBind);
540
+ // if nextSlector was supplied, populate it
541
+ if(slider.settings.nextSelector){
542
+ $(slider.settings.nextSelector).append(slider.controls.next);
543
+ }
544
+ // if prevSlector was supplied, populate it
545
+ if(slider.settings.prevSelector){
546
+ $(slider.settings.prevSelector).append(slider.controls.prev);
547
+ }
548
+ // if no custom selectors were supplied
549
+ if(!slider.settings.nextSelector && !slider.settings.prevSelector){
550
+ // add the controls to the DOM
551
+ slider.controls.directionEl = $('<div class="bx-controls-direction" />');
552
+ // add the control elements to the directionEl
553
+ slider.controls.directionEl.append(slider.controls.prev).append(slider.controls.next);
554
+ // slider.viewport.append(slider.controls.directionEl);
555
+ slider.controls.el.addClass('bx-has-controls-direction').append(slider.controls.directionEl);
556
+ }
557
+ }
558
+
559
+ /**
560
+ * Appends start / stop auto controls to the controls element
561
+ */
562
+ var appendControlsAuto = function(){
563
+ slider.controls.start = $('<div class="bx-controls-auto-item"><a class="bx-start" href="">' + slider.settings.startText + '</a></div>');
564
+ slider.controls.stop = $('<div class="bx-controls-auto-item"><a class="bx-stop" href="">' + slider.settings.stopText + '</a></div>');
565
+ // add the controls to the DOM
566
+ slider.controls.autoEl = $('<div class="bx-controls-auto" />');
567
+ // bind click actions to the controls
568
+ slider.controls.autoEl.delegate('.bx-start', 'click', clickStartBind);
569
+ slider.controls.autoEl.delegate('.bx-stop', 'click', clickStopBind);
570
+ // if autoControlsCombine, insert only the "start" control
571
+ if(slider.settings.autoControlsCombine){
572
+ slider.controls.autoEl.append(slider.controls.start);
573
+ // if autoControlsCombine is false, insert both controls
574
+ }else{
575
+ slider.controls.autoEl.append(slider.controls.start).append(slider.controls.stop);
576
+ }
577
+ // if auto controls selector was supplied, populate it with the controls
578
+ if(slider.settings.autoControlsSelector){
579
+ $(slider.settings.autoControlsSelector).html(slider.controls.autoEl);
580
+ // if auto controls selector was not supplied, add it after the wrapper
581
+ }else{
582
+ slider.controls.el.addClass('bx-has-controls-auto').append(slider.controls.autoEl);
583
+ }
584
+ // update the auto controls
585
+ updateAutoControls(slider.settings.autoStart ? 'stop' : 'start');
586
+ }
587
+
588
+ /**
589
+ * Appends image captions to the DOM
590
+ */
591
+ var appendCaptions = function(){
592
+ // cycle through each child
593
+ slider.children.each(function(index){
594
+ // get the image title attribute
595
+ var title = $(this).find('img:first').attr('title');
596
+ // append the caption
597
+ if (title != undefined) $(this).append('<div class="bx-caption"><span>' + title + '</span></div>');
158
598
  });
159
599
  }
160
- // gallery animation
161
- function prevSlide() {
162
- _prevIndex = _currentIndex;
163
- if(_currentIndex > 0) _currentIndex--;
164
- else {
165
- if(_noCycle) return;
166
- else _currentIndex = _slideCount-1;
167
- }
168
- switchSlide();
169
- }
170
- function nextSlide() {
171
- _prevIndex = _currentIndex;
172
- if(_currentIndex < _slideCount-1) _currentIndex++;
173
- else {
174
- if(_noCycle) return;
175
- else _currentIndex = 0;
176
- }
177
- switchSlide();
178
- }
179
- function refreshStatus() {
180
- if(_pagerLinks.length) _pagerLinks.removeClass(_activeClass).eq(_currentIndex).addClass(_activeClass);
181
- if(_currentNum) _currentNum.text(_currentIndex+1);
182
- if(_allNum) _allNum.text(_slideCount);
183
- _slides.eq(_prevIndex).removeClass(_activeClass);
184
- _slides.eq(_currentIndex).addClass(_activeClass);
185
- if(_noCycle) {
186
- if(_btnPrev.length) {
187
- if(_currentIndex == 0) _btnPrev.addClass(_disabledClass);
188
- else _btnPrev.removeClass(_disabledClass);
189
- }
190
- if(_btnNext.length) {
191
- if(_currentIndex == _slideCount-1) _btnNext.addClass(_disabledClass);
192
- else _btnNext.removeClass(_disabledClass);
193
- }
194
- }
195
- if(typeof _onChange === 'function') {
196
- _onChange(_this, _currentIndex);
197
- }
198
- }
199
- function switchSlide() {
200
- _slides.eq(_prevIndex).stop().animate({opacity:0},{duration: _duration, queue: false,complete:function(){
201
- jQuery(this).css({display:'none'});
202
- }})
203
- _slides.eq(_currentIndex).stop().css({display:'block',opacity:0}).animate({opacity:1},{duration: _duration, queue: false,complete:function(){
204
- jQuery(this).css({opacity:''});
205
- }})
206
- _caption.eq(_prevIndex).fadeOut();
207
- _caption.eq(_currentIndex).fadeIn();
208
- if(_autoHeight) _slides.eq(_currentIndex).parent().animate({height:_slides.eq(_currentIndex).outerHeight(true)},{duration:_duration,queue:false});
209
- refreshStatus();
210
- autoSlide();
600
+
601
+ /**
602
+ * Click next binding
603
+ *
604
+ * @param e (event)
605
+ * - DOM event object
606
+ */
607
+ var clickNextBind = function(e){
608
+ // if auto show is running, stop it
609
+ if (slider.settings.auto) el.stopAuto();
610
+ el.goToNextSlide();
611
+ e.preventDefault();
612
+ }
613
+
614
+ /**
615
+ * Click prev binding
616
+ *
617
+ * @param e (event)
618
+ * - DOM event object
619
+ */
620
+ var clickPrevBind = function(e){
621
+ // if auto show is running, stop it
622
+ if (slider.settings.auto) el.stopAuto();
623
+ el.goToPrevSlide();
624
+ e.preventDefault();
625
+ }
626
+
627
+ /**
628
+ * Click start binding
629
+ *
630
+ * @param e (event)
631
+ * - DOM event object
632
+ */
633
+ var clickStartBind = function(e){
634
+ el.startAuto();
635
+ e.preventDefault();
636
+ }
637
+
638
+ /**
639
+ * Click stop binding
640
+ *
641
+ * @param e (event)
642
+ * - DOM event object
643
+ */
644
+ var clickStopBind = function(e){
645
+ el.stopAuto();
646
+ e.preventDefault();
211
647
  }
212
648
 
213
- // autoslide function
214
- function autoSlide() {
215
- if(!_autoRotation || _hover) return;
216
- if(_timer) clearTimeout(_timer);
217
- _timer = setTimeout(nextSlide,_switchTime+_duration);
218
- }
219
- if(_pauseOnHover) {
220
- _this.hover(function(){
221
- _hover = true;
222
- if(_timer) clearTimeout(_timer);
223
- },function(){
224
- _hover = false;
225
- autoSlide();
226
- });
649
+ /**
650
+ * Click pager binding
651
+ *
652
+ * @param e (event)
653
+ * - DOM event object
654
+ */
655
+ var clickPagerBind = function(e){
656
+ // if auto show is running, stop it
657
+ if (slider.settings.auto) el.stopAuto();
658
+ var pagerLink = $(e.currentTarget);
659
+ var pagerIndex = parseInt(pagerLink.attr('data-slide-index'));
660
+ // if clicked pager link is not active, continue with the goToSlide call
661
+ if(pagerIndex != slider.active.index) el.goToSlide(pagerIndex);
662
+ e.preventDefault();
663
+ }
664
+
665
+ /**
666
+ * Updates the pager links with an active class
667
+ *
668
+ * @param slideIndex (int)
669
+ * - index of slide to make active
670
+ */
671
+ var updatePagerActive = function(slideIndex){
672
+ // if "short" pager type
673
+ if(slider.settings.pagerType == 'short'){
674
+ slider.pagerEl.html((slideIndex + 1) + slider.settings.pagerShortSeparator + slider.children.length);
675
+ return;
676
+ }
677
+ // remove all pager active classes
678
+ slider.pagerEl.find('a').removeClass('active');
679
+ // apply the active class
680
+ slider.pagerEl.find('a').eq(slideIndex).addClass('active');
681
+ }
682
+
683
+ /**
684
+ * Performs needed actions after a slide transition
685
+ */
686
+ var updateAfterSlideTransition = function(){
687
+ // if infinte loop is true
688
+ if(slider.settings.infiniteLoop){
689
+ var position = '';
690
+ // first slide
691
+ if(slider.active.index == 0){
692
+ // set the new position
693
+ position = slider.children.eq(0).position();
694
+ // carousel, last slide
695
+ }else if(slider.active.index == getPagerQty() - 1 && slider.carousel){
696
+ position = slider.children.eq((getPagerQty() - 1) * getMoveBy()).position();
697
+ // last slide
698
+ }else if(slider.active.index == slider.children.length - 1){
699
+ position = slider.children.eq(slider.children.length - 1).position();
700
+ }
701
+ if (slider.settings.mode == 'horizontal') { setPositionProperty(-position.left, 'reset', 0);; }
702
+ else if (slider.settings.mode == 'vertical') { setPositionProperty(-position.top, 'reset', 0);; }
703
+ }
704
+ // declare that the transition is complete
705
+ slider.working = false;
706
+ // onSlideAfter callback
707
+ slider.settings.onSlideAfter(slider.children.eq(slider.active.index), slider.oldIndex, slider.active.index);
708
+ }
709
+
710
+ /**
711
+ * Updates the auto controls state (either active, or combined switch)
712
+ *
713
+ * @param state (string) "start", "stop"
714
+ * - the new state of the auto show
715
+ */
716
+ var updateAutoControls = function(state){
717
+ // if autoControlsCombine is true, replace the current control with the new state
718
+ if(slider.settings.autoControlsCombine){
719
+ slider.controls.autoEl.html(slider.controls[state]);
720
+ // if autoControlsCombine is false, apply the "active" class to the appropriate control
721
+ }else{
722
+ slider.controls.autoEl.find('a').removeClass('active');
723
+ slider.controls.autoEl.find('a:not(.bx-' + state + ')').addClass('active');
724
+ }
725
+ }
726
+
727
+ /**
728
+ * Updates the direction controls (checks if either should be hidden)
729
+ */
730
+ var updateDirectionControls = function(){
731
+ // if infiniteLoop is false and hideControlOnEnd is true
732
+ if(!slider.settings.infiniteLoop && slider.settings.hideControlOnEnd){
733
+ // if first slide
734
+ if (slider.active.index == 0){
735
+ slider.controls.prev.addClass('disabled');
736
+ slider.controls.next.removeClass('disabled');
737
+ // if last slide
738
+ }else if(slider.active.index == getPagerQty() - 1){
739
+ slider.controls.next.addClass('disabled');
740
+ slider.controls.prev.removeClass('disabled');
741
+ // if any slide in the middle
742
+ }else{
743
+ slider.controls.prev.removeClass('disabled');
744
+ slider.controls.next.removeClass('disabled');
745
+ }
746
+ }
747
+ }
748
+
749
+ /**
750
+ * Initialzes the auto process
751
+ */
752
+ var initAuto = function(){
753
+ // if autoDelay was supplied, launch the auto show using a setTimeout() call
754
+ if(slider.settings.autoDelay > 0){
755
+ var timeout = setTimeout(el.startAuto, slider.settings.autoDelay);
756
+ // if autoDelay was not supplied, start the auto show normally
757
+ }else{
758
+ el.startAuto();
759
+ }
760
+ // if autoHover is requested
761
+ if(slider.settings.autoHover){
762
+ // on el hover
763
+ el.hover(function(){
764
+ // if the auto show is currently playing (has an active interval)
765
+ if(slider.interval){
766
+ // stop the auto show and pass true agument which will prevent control update
767
+ el.stopAuto(true);
768
+ // create a new autoPaused value which will be used by the relative "mouseout" event
769
+ slider.autoPaused = true;
770
+ }
771
+ }, function(){
772
+ // if the autoPaused value was created be the prior "mouseover" event
773
+ if(slider.autoPaused){
774
+ // start the auto show and pass true agument which will prevent control update
775
+ el.startAuto(true);
776
+ // reset the autoPaused value
777
+ slider.autoPaused = null;
778
+ }
779
+ });
780
+ }
781
+ }
782
+
783
+ /**
784
+ * Initialzes the ticker process
785
+ */
786
+ var initTicker = function(){
787
+ var startPosition = 0;
788
+ // if autoDirection is "next", append a clone of the entire slider
789
+ if(slider.settings.autoDirection == 'next'){
790
+ el.append(slider.children.clone().addClass('bx-clone'));
791
+ // if autoDirection is "prev", prepend a clone of the entire slider, and set the left position
792
+ }else{
793
+ el.prepend(slider.children.clone().addClass('bx-clone'));
794
+ var position = slider.children.first().position();
795
+ startPosition = slider.settings.mode == 'horizontal' ? -position.left : -position.top;
796
+ }
797
+ setPositionProperty(startPosition, 'reset', 0);
798
+ // do not allow controls in ticker mode
799
+ slider.settings.pager = false;
800
+ slider.settings.controls = false;
801
+ slider.settings.autoControls = false;
802
+ // if autoHover is requested
803
+ if(slider.settings.tickerHover && !slider.usingCSS){
804
+ // on el hover
805
+ slider.viewport.hover(function(){
806
+ el.stop();
807
+ }, function(){
808
+ // calculate the total width of children (used to calculate the speed ratio)
809
+ var totalDimens = 0;
810
+ slider.children.each(function(index){
811
+ totalDimens += slider.settings.mode == 'horizontal' ? $(this).outerWidth(true) : $(this).outerHeight(true);
812
+ });
813
+ // calculate the speed ratio (used to determine the new speed to finish the paused animation)
814
+ var ratio = slider.settings.speed / totalDimens;
815
+ // determine which property to use
816
+ var property = slider.settings.mode == 'horizontal' ? 'left' : 'top';
817
+ // calculate the new speed
818
+ var newSpeed = ratio * (totalDimens - (Math.abs(parseInt(el.css(property)))));
819
+ tickerLoop(newSpeed);
820
+ });
821
+ }
822
+ // start the ticker loop
823
+ tickerLoop();
824
+ }
825
+
826
+ /**
827
+ * Runs a continuous loop, news ticker-style
828
+ */
829
+ var tickerLoop = function(resumeSpeed){
830
+ speed = resumeSpeed ? resumeSpeed : slider.settings.speed;
831
+ var position = {left: 0, top: 0};
832
+ var reset = {left: 0, top: 0};
833
+ // if "next" animate left position to last child, then reset left to 0
834
+ if(slider.settings.autoDirection == 'next'){
835
+ position = el.find('.bx-clone').first().position();
836
+ // if "prev" animate left position to 0, then reset left to first non-clone child
837
+ }else{
838
+ reset = slider.children.first().position();
839
+ }
840
+ var animateProperty = slider.settings.mode == 'horizontal' ? -position.left : -position.top;
841
+ var resetValue = slider.settings.mode == 'horizontal' ? -reset.left : -reset.top;
842
+ var params = {resetValue: resetValue};
843
+ setPositionProperty(animateProperty, 'ticker', speed, params);
844
+ }
845
+
846
+ /**
847
+ * Initializes touch events
848
+ */
849
+ var initTouch = function(){
850
+ // initialize object to contain all touch values
851
+ slider.touch = {
852
+ start: {x: 0, y: 0},
853
+ end: {x: 0, y: 0}
854
+ }
855
+ slider.viewport.bind('touchstart', onTouchStart);
856
+ }
857
+
858
+ /**
859
+ * Event handler for "touchstart"
860
+ *
861
+ * @param e (event)
862
+ * - DOM event object
863
+ */
864
+ var onTouchStart = function(e){
865
+ if(slider.working){
866
+ e.preventDefault();
867
+ }else{
868
+ // record the original position when touch starts
869
+ slider.touch.originalPos = el.position();
870
+ var orig = e.originalEvent;
871
+ // record the starting touch x, y coordinates
872
+ slider.touch.start.x = orig.changedTouches[0].pageX;
873
+ slider.touch.start.y = orig.changedTouches[0].pageY;
874
+ // bind a "touchmove" event to the viewport
875
+ slider.viewport.bind('touchmove', onTouchMove);
876
+ // bind a "touchend" event to the viewport
877
+ slider.viewport.bind('touchend', onTouchEnd);
878
+ }
879
+ }
880
+
881
+ /**
882
+ * Event handler for "touchmove"
883
+ *
884
+ * @param e (event)
885
+ * - DOM event object
886
+ */
887
+ var onTouchMove = function(e){
888
+ e.preventDefault();
889
+ if(slider.settings.mode != 'fade'){
890
+ var orig = e.originalEvent;
891
+ var value = 0;
892
+ // if horizontal, drag along x axis
893
+ if(slider.settings.mode == 'horizontal'){
894
+ var change = orig.changedTouches[0].pageX - slider.touch.start.x;
895
+ value = slider.touch.originalPos.left + change;
896
+ // if vertical, drag along y axis
897
+ }else{
898
+ var change = orig.changedTouches[0].pageY - slider.touch.start.y;
899
+ value = slider.touch.originalPos.top + change;
900
+ }
901
+ setPositionProperty(value, 'reset', 0);
902
+ }
903
+ }
904
+
905
+ /**
906
+ * Event handler for "touchend"
907
+ *
908
+ * @param e (event)
909
+ * - DOM event object
910
+ */
911
+ var onTouchEnd = function(e){
912
+ slider.viewport.unbind('touchmove', onTouchMove);
913
+ var orig = e.originalEvent;
914
+ var value = 0;
915
+ // record end x, y positions
916
+ slider.touch.end.x = orig.changedTouches[0].pageX;
917
+ slider.touch.end.y = orig.changedTouches[0].pageY;
918
+ // if fade mode, check if absolute x distance clears the threshold
919
+ if(slider.settings.mode == 'fade'){
920
+ var distance = Math.abs(slider.touch.start.x - slider.touch.end.x);
921
+ if(distance >= slider.settings.swipeThreshold){
922
+ slider.touch.start.x > slider.touch.end.x ? el.goToNextSlide() : el.goToPrevSlide();
923
+ el.stopAuto();
924
+ }
925
+ // not fade mode
926
+ }else{
927
+ var distance = 0;
928
+ // calculate distance and el's animate property
929
+ if(slider.settings.mode == 'horizontal'){
930
+ distance = slider.touch.end.x - slider.touch.start.x;
931
+ value = slider.touch.originalPos.left;
932
+ }else{
933
+ distance = slider.touch.end.y - slider.touch.start.y;
934
+ value = slider.touch.originalPos.top;
935
+ }
936
+ // if not infinite loop and first / last slide, do not attempt a slide transition
937
+ if(!slider.settings.infiniteLoop && ((slider.active.index == 0 && distance > 0) || (slider.active.last && distance < 0))){
938
+ setPositionProperty(value, 'reset', 200);
939
+ }else{
940
+ // check if distance clears threshold
941
+ if(Math.abs(distance) >= slider.settings.swipeThreshold){
942
+ distance < 0 ? el.goToNextSlide() : el.goToPrevSlide();
943
+ el.stopAuto();
944
+ }else{
945
+ // el.animate(property, 200);
946
+ setPositionProperty(value, 'reset', 200);
947
+ }
948
+ }
949
+ }
950
+ slider.viewport.unbind('touchend', onTouchEnd);
227
951
  }
228
- refreshStatus();
229
- autoSlide();
230
- });
231
- };
952
+
953
+ /**
954
+ * ===================================================================================
955
+ * = PUBLIC FUNCTIONS
956
+ * ===================================================================================
957
+ */
958
+
959
+ /**
960
+ * Performs slide transition to the specified slide
961
+ *
962
+ * @param slideIndex (int)
963
+ * - the destination slide's index (zero-based)
964
+ *
965
+ * @param direction (string)
966
+ * - INTERNAL USE ONLY - the direction of travel ("prev" / "next")
967
+ */
968
+ el.goToSlide = function(slideIndex, direction){
969
+ // if plugin is currently in motion, ignore request
970
+ if(slider.working || slider.active.index == slideIndex) return;
971
+ // declare that plugin is in motion
972
+ slider.working = true;
973
+ // store the old index
974
+ slider.oldIndex = slider.active.index;
975
+ // if slideIndex is less than zero, set active index to last child (this happens during infinite loop)
976
+ if(slideIndex < 0){
977
+ slider.active.index = getPagerQty() - 1;
978
+ // if slideIndex is greater than children length, set active index to 0 (this happens during infinite loop)
979
+ }else if(slideIndex >= getPagerQty()){
980
+ slider.active.index = 0;
981
+ // set active index to requested slide
982
+ }else{
983
+ slider.active.index = slideIndex;
984
+ }
985
+ // onSlideBefore, onSlideNext, onSlidePrev callbacks
986
+ slider.settings.onSlideBefore(slider.children.eq(slider.active.index), slider.oldIndex, slider.active.index);
987
+ if(direction == 'next'){
988
+ slider.settings.onSlideNext(slider.children.eq(slider.active.index), slider.oldIndex, slider.active.index);
989
+ }else if(direction == 'prev'){
990
+ slider.settings.onSlidePrev(slider.children.eq(slider.active.index), slider.oldIndex, slider.active.index);
991
+ }
992
+ // check if last slide
993
+ slider.active.last = slider.active.index >= getPagerQty() - 1;
994
+ // update the pager with active class
995
+ if(slider.settings.pager) updatePagerActive(slider.active.index);
996
+ // // check for direction control update
997
+ if(slider.settings.controls) updateDirectionControls();
998
+ // if slider is set to mode: "fade"
999
+ if(slider.settings.mode == 'fade'){
1000
+ // if adaptiveHeight is true and next height is different from current height, animate to the new height
1001
+ if(slider.settings.adaptiveHeight && slider.viewport.height() != getViewportHeight()){
1002
+ slider.viewport.animate({height: getViewportHeight()}, slider.settings.adaptiveHeightSpeed);
1003
+ }
1004
+ // fade out the visible child and reset its z-index value
1005
+ slider.children.filter(':visible').fadeOut(slider.settings.speed).css({zIndex: 0});
1006
+ // fade in the newly requested slide
1007
+ slider.children.eq(slider.active.index).css('zIndex', 51).fadeIn(slider.settings.speed, function(){
1008
+ $(this).css('zIndex', 50);
1009
+ updateAfterSlideTransition();
1010
+ });
1011
+ // slider mode is not "fade"
1012
+ }else{
1013
+ // if adaptiveHeight is true and next height is different from current height, animate to the new height
1014
+ if(slider.settings.adaptiveHeight && slider.viewport.height() != getViewportHeight()){
1015
+ slider.viewport.animate({height: getViewportHeight()}, slider.settings.adaptiveHeightSpeed);
1016
+ }
1017
+ var moveBy = 0;
1018
+ var position = {left: 0, top: 0};
1019
+ // if carousel and not infinite loop
1020
+ if(!slider.settings.infiniteLoop && slider.carousel && slider.active.last){
1021
+ if(slider.settings.mode == 'horizontal'){
1022
+ // get the last child position
1023
+ var lastChild = slider.children.eq(slider.children.length - 1);
1024
+ position = lastChild.position();
1025
+ // calculate the position of the last slide
1026
+ moveBy = slider.viewport.width() - lastChild.width();
1027
+ }else{
1028
+ // get last showing index position
1029
+ var lastShowingIndex = slider.children.length - slider.settings.minSlides;
1030
+ position = slider.children.eq(lastShowingIndex).position();
1031
+ }
1032
+ // horizontal carousel, going previous while on first slide (infiniteLoop mode)
1033
+ }else if(slider.carousel && slider.active.last && direction == 'prev'){
1034
+ // get the last child position
1035
+ var eq = slider.settings.moveSlides == 1 ? slider.settings.maxSlides - getMoveBy() : ((getPagerQty() - 1) * getMoveBy()) - (slider.children.length - slider.settings.maxSlides);
1036
+ var lastChild = el.children('.bx-clone').eq(eq);
1037
+ position = lastChild.position();
1038
+ // if infinite loop and "Next" is clicked on the last slide
1039
+ }else if(direction == 'next' && slider.active.index == 0){
1040
+ // get the last clone position
1041
+ position = el.find('.bx-clone').eq(slider.settings.maxSlides).position();
1042
+ slider.active.last = false;
1043
+ // normal non-zero requests
1044
+ }else if(slideIndex >= 0){
1045
+ var requestEl = slideIndex * getMoveBy();
1046
+ position = slider.children.eq(requestEl).position();
1047
+ }
1048
+ // plugin values to be animated
1049
+ var value = slider.settings.mode == 'horizontal' ? -(position.left - moveBy) : -position.top;
1050
+ setPositionProperty(value, 'slide', slider.settings.speed);
1051
+ }
1052
+ }
1053
+
1054
+ /**
1055
+ * Transitions to the next slide in the show
1056
+ */
1057
+ el.goToNextSlide = function(){
1058
+ // if infiniteLoop is false and last page is showing, disregard call
1059
+ if (!slider.settings.infiniteLoop && slider.active.last) return;
1060
+ var pagerIndex = slider.active.index + 1;
1061
+ el.goToSlide(pagerIndex, 'next');
1062
+ }
1063
+
1064
+ /**
1065
+ * Transitions to the prev slide in the show
1066
+ */
1067
+ el.goToPrevSlide = function(){
1068
+ // if infiniteLoop is false and last page is showing, disregard call
1069
+ if (!slider.settings.infiniteLoop && slider.active.index == 0) return;
1070
+ var pagerIndex = slider.active.index - 1;
1071
+ el.goToSlide(pagerIndex, 'prev');
1072
+ }
1073
+
1074
+ /**
1075
+ * Starts the auto show
1076
+ *
1077
+ * @param preventControlUpdate (boolean)
1078
+ * - if true, auto controls state will not be updated
1079
+ */
1080
+ el.startAuto = function(preventControlUpdate){
1081
+ // if an interval already exists, disregard call
1082
+ if(slider.interval) return;
1083
+ // create an interval
1084
+ slider.interval = setInterval(function(){
1085
+ slider.settings.autoDirection == 'next' ? el.goToNextSlide() : el.goToPrevSlide();
1086
+ }, slider.settings.pause);
1087
+ // if auto controls are displayed and preventControlUpdate is not true
1088
+ if (slider.settings.autoControls && preventControlUpdate != true) updateAutoControls('stop');
1089
+ }
1090
+
1091
+ /**
1092
+ * Stops the auto show
1093
+ *
1094
+ * @param preventControlUpdate (boolean)
1095
+ * - if true, auto controls state will not be updated
1096
+ */
1097
+ el.stopAuto = function(preventControlUpdate){
1098
+ // if no interval exists, disregard call
1099
+ if(!slider.interval) return;
1100
+ // clear the interval
1101
+ clearInterval(slider.interval);
1102
+ slider.interval = null;
1103
+ // if auto controls are displayed and preventControlUpdate is not true
1104
+ if (slider.settings.autoControls && preventControlUpdate != true) updateAutoControls('start');
1105
+ }
1106
+
1107
+ /**
1108
+ * Returns current slide index (zero-based)
1109
+ */
1110
+ el.getCurrentSlide = function(){
1111
+ return slider.active.index;
1112
+ }
1113
+
1114
+ /**
1115
+ * Returns number of slides in show
1116
+ */
1117
+ el.getSlideCount = function(){
1118
+ return slider.children.length;
1119
+ }
1120
+
1121
+ /**
1122
+ * Makes slideshow responsive
1123
+ */
1124
+ // first get the original window dimens (thanks alot IE)
1125
+ var windowWidth = $(window).width();
1126
+ var windowHeight = $(window).height();
1127
+ $(window).resize(function(){
1128
+ // get the new window dimens (again, thank you IE)
1129
+ var windowWidthNew = $(window).width();
1130
+ var windowHeightNew = $(window).height();
1131
+ // make sure that it is a true window resize
1132
+ // *we must check this because our dinosaur friend IE fires a window resize event when certain DOM elements
1133
+ // are resized. Can you just die already?*
1134
+ if(windowWidth != windowWidthNew || windowHeight != windowHeightNew){
1135
+ // set the new window dimens
1136
+ windowWidth = windowWidthNew;
1137
+ windowHeight = windowHeightNew;
1138
+ // resize all children in ratio to new screen size
1139
+ slider.children.add(el.find('.bx-clone')).width(getSlideWidth());
1140
+ // adjust the height
1141
+ slider.viewport.css('height', getViewportHeight());
1142
+ // if active.last was true before the screen resize, we want
1143
+ // to keep it last no matter what screen size we end on
1144
+ if (slider.active.last) slider.active.index = getPagerQty() - 1;
1145
+ // if the active index (page) no longer exists due to the resize, simply set the index as last
1146
+ if (slider.active.index >= getPagerQty()) slider.active.last = true;
1147
+ // if a pager is being displayed and a custom pager is not being used, update it
1148
+ if(slider.settings.pager && !slider.settings.pagerCustom){
1149
+ populatePager();
1150
+ updatePagerActive(slider.active.index);
1151
+ }
1152
+ // update the slide position
1153
+ if(!slider.settings.ticker) setSlidePosition();
1154
+ }
1155
+ });
1156
+
1157
+ init();
1158
+
1159
+ // returns the current jQuery object
1160
+ return this;
1161
+ }
1162
+
1163
+ })(jQuery);
1164
+
1165
+ /*!
1166
+ * jQuery imagesLoaded plugin v2.1.0
1167
+ * http://github.com/desandro/imagesloaded
1168
+ *
1169
+ * MIT License. by Paul Irish et al.
1170
+ */
1171
+
1172
+ /*jshint curly: true, eqeqeq: true, noempty: true, strict: true, undef: true, browser: true */
1173
+ /*global jQuery: false */
1174
+
1175
+ (function(c,n){var l="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==";c.fn.imagesLoaded=function(f){function m(){var b=c(i),a=c(h);d&&(h.length?d.reject(e,b,a):d.resolve(e));c.isFunction(f)&&f.call(g,e,b,a)}function j(b,a){b.src===l||-1!==c.inArray(b,k)||(k.push(b),a?h.push(b):i.push(b),c.data(b,"imagesLoaded",{isBroken:a,src:b.src}),o&&d.notifyWith(c(b),[a,e,c(i),c(h)]),e.length===k.length&&(setTimeout(m),e.unbind(".imagesLoaded")))}var g=this,d=c.isFunction(c.Deferred)?c.Deferred():
1176
+ 0,o=c.isFunction(d.notify),e=g.find("img").add(g.filter("img")),k=[],i=[],h=[];c.isPlainObject(f)&&c.each(f,function(b,a){if("callback"===b)f=a;else if(d)d[b](a)});e.length?e.bind("load.imagesLoaded error.imagesLoaded",function(b){j(b.target,"error"===b.type)}).each(function(b,a){var d=a.src,e=c.data(a,"imagesLoaded");if(e&&e.src===d)j(a,e.isBroken);else if(a.complete&&a.naturalWidth!==n)j(a,0===a.naturalWidth||0===a.naturalHeight);else if(a.readyState||a.complete)a.src=l,a.src=d}):m();return d?d.promise(g):
1177
+ g}})(jQuery);