1/** 2 * BxSlider v4.1.2 - Fully loaded, responsive content slider 3 * http://bxslider.com 4 * 5 * Copyright 2014, Steven Wanderski - http://stevenwanderski.com - http://bxcreative.com 6 * Written while drinking Belgian ales and listening to jazz 7 * 8 * Released under the MIT license - http://opensource.org/licenses/MIT 9 */ 10 /* ===================================================================================== */ 11 /** 12 * Custom modifications of one of my favourite responsive sliders. 13 * --------------------------------------------------------------------------------------- 14 * - Author: Rahisify 15 * - Url : http://rahisify.com 16 * --------------------------------------------------------------------------------------- 17 * (1) Added data attributes support 18 * (2) Added break points support 19 * (3) Added automatic reload option 20 * (4) Added automatic slide width calculation 21 * (4) Added self calling capability 22 * --------------------------------------------------------------------------------------- 23 * - Would not be possible without the awesome work of Steven Wanderski. 24 * - Released under same license - not for sale! 25 * --------------------------------------------------------------------------------------- 26 */ 27 28;(function($){ 29 30 var plugin = {}; 31 32 var defaults = { 33 34 // GENERAL 35 mode: 'horizontal', 36 slideSelector: '', 37 infiniteLoop: true, 38 hideControlOnEnd: false, 39 speed: 500, 40 easing: null, 41 slideMargin: 0, 42 startSlide: 0, 43 randomStart: false, 44 captions: false, 45 ticker: false, 46 tickerHover: false, 47 adaptiveHeight: false, 48 adaptiveHeightSpeed: 500, 49 video: false, 50 useCSS: true, 51 preloadImages: 'visible', 52 responsive: true, 53 slideZIndex: 50, 54 wrapperClass: 'bx-wrapper', 55 56 // TOUCH 57 touchEnabled: true, 58 swipeThreshold: 50, 59 oneToOneTouch: true, 60 preventDefaultSwipeX: true, 61 preventDefaultSwipeY: false, 62 63 // PAGER 64 pager: true, 65 pagerType: 'full', 66 pagerShortSeparator: ' / ', 67 pagerSelector: null, 68 buildPager: null, 69 pagerCustom: null, 70 71 // CONTROLS 72 controls: true, 73 nextText: 'Next', 74 prevText: 'Prev', 75 nextSelector: null, 76 prevSelector: null, 77 autoControls: false, 78 startText: 'Start', 79 stopText: 'Stop', 80 autoControlsCombine: false, 81 autoControlsSelector: null, 82 83 // AUTO 84 auto: false, 85 pause: 4000, 86 autoStart: true, 87 autoDirection: 'next', 88 autoHover: false, 89 autoDelay: 0, 90 autoSlideForOnePage: false, 91 92 // CAROUSEL 93 minSlides: 1, 94 maxSlides: 1, 95 moveSlides: 0, 96 slideWidth: 0, 97 autoReload: false, 98 99 // CALLBACKS 100 onSliderLoad: function() {}, 101 onSlideBefore: function() {}, 102 onSlideAfter: function() {}, 103 onSlideNext: function() {}, 104 onSlidePrev: function() {}, 105 onSliderResize: function() {} 106 } 107 108 $.fn.bxSlider = function(options){ 109 110 if(this.length == 0) return this; 111 112 // support mutltiple elements 113 if(this.length > 1){ 114 this.each(function(){$(this).bxSlider(options)}); 115 return this; 116 } 117 118 // create a namespace to be used throughout the plugin 119 var slider = {}; 120 // set a reference to our slider element 121 var el = this; 122 plugin.el = this; 123 124 /** 125 * Makes slideshow responsive 126 */ 127 // first get the original window dimens (thanks alot IE) 128 var windowWidth = $(window).width(); 129 var windowHeight = $(window).height(); 130 131 132 133 /** 134 * =================================================================================== 135 * = PRIVATE FUNCTIONS 136 * =================================================================================== 137 */ 138 139 /** 140 * Initializes namespace settings to be used throughout plugin 141 */ 142 var init = function(){ 143 144 // merge user-supplied options with the defaults 145 slider.settings = $.extend({}, defaults, options); 146 147 /** 148 * =================================================================================== 149 * CUSTOM MODIFICATIONS (Delete this block if you disapprove!) 150 * =================================================================================== 151 */ 152 153 // set up carousel if initial options intended to do so 154 setupCarousel(); 155 156 // screen width we will be referring to 157 var currentWidth = $(window).width(); 158 // force the slider to use this width(disable if you disapprove!) 159 windowWidth = currentWidth; 160 161 /* DEFINE FUNCTIONS WE WILL USE 162 -----------------------------------------------------------------*/ 163 164 // calculates slide width 165 function calcSlideWidth (fullW, numSlides, margin) { 166 167 var calcWidth = (fullW-(margin*(numSlides-1))) / numSlides; 168 return Math.floor(calcWidth); 169 170 } 171 172 // sets break point options
173 function setBreakOptions(breakObj) { 174 175 for(var key in breakObj) { 176 slider.settings[key] = breakObj[key]; 177 } 178 179 } 180 181 // sets up carousel from available options 182 function setupCarousel() { 183 184 if(slider.settings.slides) { 185 slider.settings.maxSlides = slider.settings.slides; 186 slider.settings.minSlides = slider.settings.slides; 187 slider.settings.slideWidth = calcSlideWidth (windowWidth, slider.settings.slides, slider.settings.slideMargin); 188 } 189 190 } 191 192 // converts string into valid JSON format 193 function jsonify(str) { 194 195 str = str.replace(/([a-zA-Z0-9]+?):/g, '"$1":'); 196 str = str.replace(/'/g, '"'); 197 var jsonArray = jQuery.parseJSON(str); 198 return jsonArray; 199 200 } 201 202 // (1) Grab data options if available 203 // --------------------------------------------------------------------------------- 204 205 var dataOptions = $(el).attr('data-options'); 206 207 if(dataOptions) { 208 209 //add curly brackets if not there 210 var lastChar = dataOptions.charAt(dataOptions.length-1); 211 var firstChar = dataOptions.charAt(0); 212 213 if(firstChar != "{" && lastChar != "}" ) { 214 dataOptions = "{" + dataOptions + "}"; 215 } 216 217 // exploit JSON parser to lessen work 218 var opts = jsonify(dataOptions); 219 220 for (var key in opts) { 221 slider.settings[key] = opts[key]; 222 } 223 // set up carousel if options intended to do so 224 setupCarousel(); 225 226 } 227 228 // (2) Grab breaks from data attributes if available 229 // --------------------------------------------------------------------------------- 230 231 var dataBreaks = $(el).attr('data-breaks'); 232 233 234 if(dataBreaks) { 235 // exploit JSON parser to lessen work 236 slider.settings.breaks = jsonify(dataBreaks); 237 } 238 239 // (3) proceed to process(if available) the user supplied break points 240 // --------------------------------------------------------------------------------- 241 242 if(slider.settings.breaks) { 243 244 // Sort in ascending order in case of mix up 245 slider.settings.breaks.sort(function(a, b) { 246 return a.screen - b.screen; 247 }); 248 249 // Process breaks 250 for(var i = 0; i < slider.settings.breaks.length; ++i) { 251 252 var currentBreak = slider.settings.breaks[i]; 253 var nextBreak = {}; 254 var min = currentBreak.screen; 255 var max; 256 257 if(i < slider.settings.breaks.length - 1) { // next break exists 258 259 nextBreak = slider.settings.breaks[i+1]; 260 max = nextBreak.screen; 261 262 if(currentWidth >= min && currentWidth < max) { 263 setBreakOptions(currentBreak); 264 } 265 266 } else { // just use current break coz next one does not exist 267 268 if(currentWidth >= min) { 269 setBreakOptions(currentBreak); 270 } 271 } 272 273 } 274 275 // set up carousel if options intended to do so 276 setupCarousel(); 277 278 } 279 280 281 /** 282 * =================================================================================== 283 * = CUSTOM MODIFICATIONS /END 284 * =================================================================================== 285 */ 286 287 // parse slideWidth setting 288 slider.settings.slideWidth = parseInt(slider.settings.slideWidth); 289 // store the original children 290 slider.children = el.children(slider.settings.slideSelector); 291 // check if actual number of slides is less than minSlides / maxSlides 292 if(slider.children.length < slider.settings.minSlides) slider.settings.minSlides = slider.children.length; 293 if(slider.children.length < slider.settings.maxSlides) slider.settings.maxSlides = slider.children.length; 294 // if random start, set the startSlide setting to random number 295 if(slider.settings.randomStart) slider.settings.startSlide = Math.floor(Math.random() * slider.children.length); 296 // store active slide information 297 slider.active = { index: slider.settings.startSlide }
298 // store if the slider is in carousel mode (displaying / moving multiple slides) 299 slider.carousel = slider.settings.minSlides > 1 || slider.settings.maxSlides > 1; 300 // if carousel, force preloadImages = 'all' 301 if(slider.carousel) slider.settings.preloadImages = 'all'; 302 // calculate the min / max width thresholds based on min / max number of slides 303 // used to setup and update carousel slides dimensions 304 slider.minThreshold = (slider.settings.minSlides * slider.settings.slideWidth) + ((slider.settings.minSlides - 1) * slider.settings.slideMargin); 305 slider.maxThreshold = (slider.settings.maxSlides * slider.settings.slideWidth) + ((slider.settings.maxSlides - 1) * slider.settings.slideMargin); 306 // store the current state of the slider (if currently animating, working is true) 307 slider.working = false; 308 // initialize the controls object 309 slider.controls = {}; 310 // initialize an auto interval 311 slider.interval = null; 312 // determine which property to use for transitions 313 slider.animProp = slider.settings.mode == 'vertical' ? 'top' : 'left'; 314 // determine if hardware acceleration can be used 315 slider.usingCSS = slider.settings.useCSS && slider.settings.mode != 'fade' && (function(){ 316 // create our test div element 317 var div = document.createElement('div'); 318 // css transition properties 319 var props = ['WebkitPerspective', 'MozPerspective', 'OPerspective', 'msPerspective']; 320 // test for each property 321 for(var i in props){ 322 if(div.style[props[i]] !== undefined){ 323 slider.cssPrefix = props[i].replace('Perspective', '').toLowerCase(); 324 slider.animProp = '-' + slider.cssPrefix + '-transform'; 325 return true; 326 } 327 } 328 return false; 329 }()); 330 // if vertical mode always make maxSlides and minSlides equal 331 if(slider.settings.mode == 'vertical') slider.settings.maxSlides = slider.settings.minSlides; 332 // save original style data 333 el.data("origStyle", el.attr("style")); 334 el.children(slider.settings.slideSelector).each(function() { 335 $(this).data("origStyle", $(this).attr("style")); 336 }); 337 // perform all DOM / CSS modifications 338 setup(); 339 } 340 341 /** 342 * Performs all DOM and CSS modifications 343 */ 344 var setup = function(){ 345 // wrap el in a wrapper 346 el.wrap('<div class="' + slider.settings.wrapperClass + '"><div class="bx-viewport"></div></div>'); 347 // store a namspace reference to .bx-viewport 348 slider.viewport = el.parent(); 349 // add a loading div to display while images are loading 350 slider.loader = $('<div class="bx-loading" />'); 351 slider.viewport.prepend(slider.loader); 352 // set el to a massive width, to hold any needed slides 353 // also strip any margin and padding from el 354 el.css({ 355 width: slider.settings.mode == 'horizontal' ? (slider.children.length * 100 + 215) + '%' : 'auto', 356 position: 'relative' 357 }); 358 // if using CSS, add the easing property 359 if(slider.usingCSS && slider.settings.easing){ 360 el.css('-' + slider.cssPrefix + '-transition-timing-function', slider.settings.easing); 361 // if not using CSS and no easing value was supplied, use the default JS animation easing (swing) 362 }else if(!slider.settings.easing){ 363 slider.settings.easing = 'swing'; 364 } 365 var slidesShowing = getNumberSlidesShowing(); 366 // make modifications to the viewport (.bx-viewport) 367 slider.viewport.css({ 368 width: '100%', 369 overflow: 'hidden', 370 position: 'relative' 371 }); 372 slider.viewport.parent().css({ 373 maxWidth: getViewportMaxWidth() 374 }); 375 // make modification to the wrapper (.bx-wrapper) 376 if(!slider.settings.pager) { 377 slider.viewport.parent().css({ 378 margin: '0 auto 0px' 379 }); 380 } 381 // apply css to all slider children 382 slider.children.css({ 383 'float': slider.settings.mode == 'horizontal' ? 'left' : 'none', 384 listStyle: 'none', 385 position: 'relative' 386 }); 387 // apply the calculated width after the float is applied to prevent scrollbar interference 388 slider.children.css('width', calcSlideWidthidth()); 389 // if slideMargin is supplied, add the css 390 if(slider.settings.mode == 'horizontal' && slider.settings.slideMargin > 0) slider.children.css('marginRight', slider.settings.slideMargin); 391 if(slider.settings.mode == 'vertical' && slider.settings.slideMargin > 0) slider.children.css('marginBottom', slider.settings.slideMargin); 392 // if "fade" mode, add positioning and z-index CSS 393 if(slider.settings.mode == 'fade'){ 394 slider.children.css({ 395 position: 'absolute', 396 zIndex: 0, 397 display: 'none' 398 }); 399 // prepare the z-index on the showing element 400 slider.children.eq(slider.settings.startSlide).css({zIndex: slider.settings.slideZIndex, display: 'block'}); 401 } 402 // create an element to contain all slider controls (pager, start / stop, etc) 403 slider.controls.el = $('<div class="bx-controls" />'); 404 // if captions are requested, add them
405 if(slider.settings.captions) appendCaptions(); 406 // check if startSlide is last slide 407 slider.active.last = slider.settings.startSlide == getPagerQty() - 1; 408 // if video is true, set up the fitVids plugin 409 if(slider.settings.video) el.fitVids(); 410 // set the default preload selector (visible) 411 var preloadSelector = slider.children.eq(slider.settings.startSlide); 412 if (slider.settings.preloadImages == "all") preloadSelector = slider.children; 413 // only check for control addition if not in "ticker" mode 414 if(!slider.settings.ticker){ 415 // if pager is requested, add it 416 if(slider.settings.pager) appendPager(); 417 // if controls are requested, add them 418 if(slider.settings.controls) appendControls(); 419 // if auto is true, and auto controls are requested, add them 420 if(slider.settings.auto && slider.settings.autoControls) appendControlsAuto(); 421 // if any control option is requested, add the controls wrapper 422 if(slider.settings.controls || slider.settings.autoControls || slider.settings.pager) slider.viewport.after(slider.controls.el); 423 // if ticker mode, do not allow a pager 424 }else{ 425 slider.settings.pager = false; 426 } 427 // preload all images, then perform final DOM / CSS modifications that depend on images being loaded 428 loadElements(preloadSelector, start); 429 } 430 431 var loadElements = function(selector, callback){ 432 var total = selector.find('img, iframe').length; 433 if (total == 0){ 434 callback(); 435 return; 436 } 437 var count = 0; 438 selector.find('img, iframe').each(function(){ 439 $(this).one('load', function() { 440 if(++count == total) callback(); 441 }).each(function() { 442 if(this.complete) $(this).load(); 443 }); 444 }); 445 } 446 447 /** 448 * Start the slider 449 */ 450 var start = function(){ 451 452 // if infinite loop, prepare additional slides 453 if(slider.settings.infiniteLoop && slider.settings.mode != 'fade' && !slider.settings.ticker){ 454 var slice = slider.settings.mode == 'vertical' ? slider.settings.minSlides : slider.settings.maxSlides; 455 var sliceAppend = slider.children.slice(0, slice).clone().addClass('bx-clone'); 456 var slicePrepend = slider.children.slice(-slice).clone().addClass('bx-clone'); 457 el.append(sliceAppend).prepend(slicePrepend); 458 } 459 // remove the loading DOM element 460 slider.loader.remove(); 461 // set the left / top position of "el" 462 setSlidePosition(); 463 // if "vertical" mode, always use adaptiveHeight to prevent odd behavior 464 if (slider.settings.mode == 'vertical') slider.settings.adaptiveHeight = true; 465 // set the viewport height 466 slider.viewport.height(getViewportHeight()); 467 // make sure everything is positioned just right (same as a window resize) 468 el.redrawSlider(); 469 // onSliderLoad callback 470 slider.settings.onSliderLoad(slider.active.index); 471 // slider has been fully initialized 472 slider.initialized = true;
473 // bind the resize call to the window 474 if (slider.settings.responsive) $(window).bind('resize', resizeWindow); 475 // if auto is true and has more than 1 page, start the show 476 if (slider.settings.auto && slider.settings.autoStart && (getPagerQty() > 1 || slider.settings.autoSlideForOnePage)) initAuto(); 477 // if ticker is true, start the ticker 478 if (slider.settings.ticker) initTicker(); 479 // if pager is requested, make the appropriate pager link active 480 if (slider.settings.pager) updatePagerActive(slider.settings.startSlide); 481 // check for any updates to the controls (like hideControlOnEnd updates) 482 if (slider.settings.controls) updateDirectionControls(); 483 // if touchEnabled is true, setup the touch events 484 if (slider.settings.touchEnabled && !slider.settings.ticker) initTouch(); 485 } 486 487 /** 488 * Returns the calculated height of the viewport, used to determine either adaptiveHeight or the maxHeight value 489 */ 490 var getViewportHeight = function(){ 491 var height = 0; 492 // first determine which children (slides) should be used in our height calculation 493 var children = $(); 494 // if mode is not "vertical" and adaptiveHeight is false, include all children 495 if(slider.settings.mode != 'vertical' && !slider.settings.adaptiveHeight){ 496 children = slider.children; 497 }else{ 498 // if not carousel, return the single active child 499 if(!slider.carousel){ 500 children = slider.children.eq(slider.active.index); 501 // if carousel, return a slice of children 502 }else{ 503 // get the individual slide index 504 var currentIndex = slider.settings.moveSlides == 1 ? slider.active.index : slider.active.index * getMoveBy(); 505 // add the current slide to the children 506 children = slider.children.eq(currentIndex); 507 // cycle through the remaining "showing" slides 508 for (i = 1; i <= slider.settings.maxSlides - 1; i++){ 509 // if looped back to the start 510 if(currentIndex + i >= slider.children.length){ 511 children = children.add(slider.children.eq(i - 1)); 512 }else{ 513 children = children.add(slider.children.eq(currentIndex + i)); 514 } 515 } 516 } 517 } 518 // if "vertical" mode, calculate the sum of the heights of the children 519 if(slider.settings.mode == 'vertical'){ 520 children.each(function(index) { 521 height += $(this).outerHeight(); 522 }); 523 // add user-supplied margins 524 if(slider.settings.slideMargin > 0){ 525 height += slider.settings.slideMargin * (slider.settings.minSlides - 1); 526 } 527 // if not "vertical" mode, calculate the max height of the children 528 }else{ 529 height = Math.max.apply(Math, children.map(function(){ 530 return $(this).outerHeight(false); 531 }).get()); 532 } 533 534 if(slider.viewport.css('box-sizing') == 'border-box'){ 535 height += parseFloat(slider.viewport.css('padding-top')) + parseFloat(slider.viewport.css('padding-bottom')) + 536 parseFloat(slider.viewport.css('border-top-width')) + parseFloat(slider.viewport.css('border-bottom-width')); 537 }else if(slider.viewport.css('box-sizing') == 'padding-box'){ 538 height += parseFloat(slider.viewport.css('padding-top')) + parseFloat(slider.viewport.css('padding-bottom')); 539 } 540 541 return height; 542 } 543 544 /** 545 * Returns the calculated width to be used for the outer wrapper / viewport 546 */ 547 var getViewportMaxWidth = function(){ 548 var width = '100%'; 549 if(slider.settings.slideWidth > 0){ 550 if(slider.settings.mode == 'horizontal'){ 551 width = (slider.settings.maxSlides * slider.settings.slideWidth) + ((slider.settings.maxSlides - 1) * slider.settings.slideMargin); 552 }else{ 553 width = slider.settings.slideWidth; 554 } 555 } 556 return width; 557 } 558 559 /** 560 * Returns the calculated width to be applied to each slide 561 */ 562 var calcSlideWidthidth = function(){ 563 // start with any user-supplied slide width 564 var newElWidth = slider.settings.slideWidth; 565 // get the current viewport width 566 var wrapWidth = slider.viewport.width(); 567 // if slide width was not supplied, or is larger than the viewport use the viewport width 568 if(slider.settings.slideWidth == 0 || 569 (slider.settings.slideWidth > wrapWidth && !slider.carousel) || 570 slider.settings.mode == 'vertical'){ 571 newElWidth = wrapWidth; 572 // if carousel, use the thresholds to determine the width 573 }else if(slider.settings.maxSlides > 1 && slider.settings.mode == 'horizontal'){ 574 if(wrapWidth > slider.maxThreshold){ 575 // newElWidth = (wrapWidth - (slider.settings.slideMargin * (slider.settings.maxSlides - 1))) / slider.settings.maxSlides; 576 }else if(wrapWidth < slider.minThreshold){ 577 newElWidth = (wrapWidth - (slider.settings.slideMargin * (slider.settings.minSlides - 1))) / slider.settings.minSlides; 578 } 579 } 580 return newElWidth; 581 } 582 583 /** 584 * Returns the number of slides currently visible in the viewport (includes partially visible slides) 585 */ 586 var getNumberSlidesShowing = function(){ 587 var slidesShowing = 1; 588 if(slider.settings.mode == 'horizontal' && slider.settings.slideWidth > 0){ 589 // if viewport is smaller than minThreshold, return minSlides 590 if(slider.viewport.width() < slider.minThreshold){ 591 slidesShowing = slider.settings.minSlides; 592 // if viewport is larger than minThreshold, return maxSlides 593 }else if(slider.viewport.width() > slider.maxThreshold){ 594 slidesShowing = slider.settings.maxSlides; 595 // if viewport is between min / max thresholds, divide viewport width by first child width 596 }else{ 597 var childWidth = slider.children.first().width() + slider.settings.slideMargin; 598 slidesShowing = Math.floor((slider.viewport.width() + 599 slider.settings.slideMargin) / childWidth); 600 } 601 // if "vertical" mode, slides showing will always be minSlides 602 }else if(slider.settings.mode == 'vertical'){ 603 slidesShowing = slider.settings.minSlides; 604 } 605 return slidesShowing; 606 } 607 608 /** 609 * Returns the number of pages (one full viewport of slides is one "page") 610 */ 611 var getPagerQty = function(){ 612 var pagerQty = 0; 613 // if moveSlides is specified by the user 614 if(slider.settings.moveSlides > 0){ 615 if(slider.settings.infiniteLoop){ 616 pagerQty = Math.ceil(slider.children.length / getMoveBy()); 617 }else{ 618 // use a while loop to determine pages 619 var breakPoint = 0; 620 var counter = 0 621 // when breakpoint goes above children length, counter is the number of pages 622 while (breakPoint < slider.children.length){ 623 ++pagerQty; 624 breakPoint = counter + getNumberSlidesShowing(); 625 counter += slider.settings.moveSlides <= getNumberSlidesShowing() ? slider.settings.moveSlides : getNumberSlidesShowing(); 626 } 627 }
628 // if moveSlides is 0 (auto) divide children length by sides showing, then round up 629 }else{ 630 pagerQty = Math.ceil(slider.children.length / getNumberSlidesShowing()); 631 } 632 return pagerQty; 633 } 634 635 /** 636 * Returns the number of indivual slides by which to shift the slider 637 */ 638 var getMoveBy = function(){ 639 // if moveSlides was set by the user and moveSlides is less than number of slides showing 640 if(slider.settings.moveSlides > 0 && slider.settings.moveSlides <= getNumberSlidesShowing()){ 641 return slider.settings.moveSlides; 642 } 643 // if moveSlides is 0 (auto) 644 return getNumberSlidesShowing(); 645 } 646 647 /** 648 * Sets the slider's (el) left or top position 649 */ 650 var setSlidePosition = function(){ 651 // if last slide, not infinite loop, and number of children is larger than specified maxSlides 652 if(slider.children.length > slider.settings.maxSlides && slider.active.last && !slider.settings.infiniteLoop){ 653 if (slider.settings.mode == 'horizontal'){ 654 // get the last child's position 655 var lastChild = slider.children.last(); 656 var position = lastChild.position(); 657 // set the left position 658 setPositionProperty(-(position.left - (slider.viewport.width() - lastChild.outerWidth())), 'reset', 0); 659 }else if(slider.settings.mode == 'vertical'){ 660 // get the last showing index's position 661 var lastShowingIndex = slider.children.length - slider.settings.minSlides; 662 var position = slider.children.eq(lastShowingIndex).position(); 663 // set the top position 664 setPositionProperty(-position.top, 'reset', 0); 665 } 666 // if not last slide 667 }else{ 668 // get the position of the first showing slide 669 var position = slider.children.eq(slider.active.index * getMoveBy()).position(); 670 // check for last slide 671 if (slider.active.index == getPagerQty() - 1) slider.active.last = true; 672 // set the repective position 673 if (position != undefined){ 674 if (slider.settings.mode == 'horizontal') setPositionProperty(-position.left, 'reset', 0); 675 else if (slider.settings.mode == 'vertical') setPositionProperty(-position.top, 'reset', 0); 676 } 677 } 678 } 679 680 /** 681 * Sets the el's animating property position (which in turn will sometimes animate el). 682 * If using CSS, sets the transform property. If not using CSS, sets the top / left property. 683 * 684 * @param value (int) 685 * - the animating property's value 686 * 687 * @param type (string) 'slider', 'reset', 'ticker' 688 * - the type of instance for which the function is being 689 * 690 * @param duration (int) 691 * - the amount of time (in ms) the transition should occupy 692 * 693 * @param params (array) optional 694 * - an optional parameter containing any variables that need to be passed in 695 */ 696 var setPositionProperty = function(value, type, duration, params){ 697 // use CSS transform 698 if(slider.usingCSS){ 699 // determine the translate3d value 700 var propValue = slider.settings.mode == 'vertical' ? 'translate3d(0, ' + value + 'px, 0)' : 'translate3d(' + value + 'px, 0, 0)'; 701 // add the CSS transition-duration 702 el.css('-' + slider.cssPrefix + '-transition-duration', duration / 1000 + 's'); 703 if(type == 'slide'){ 704 // set the property value 705 el.css(slider.animProp, propValue); 706 // bind a callback method - executes when CSS transition completes 707 el.bind('transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd', function(){ 708 // unbind the callback 709 el.unbind('transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd'); 710 updateAfterSlideTransition(); 711 }); 712 }else if(type == 'reset'){ 713 el.css(slider.animProp, propValue); 714 }else if(type == 'ticker'){ 715 // make the transition use 'linear' 716 el.css('-' + slider.cssPrefix + '-transition-timing-function', 'linear'); 717 el.css(slider.animProp, propValue); 718 // bind a callback method - executes when CSS transition completes 719 el.bind('transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd', function(){ 720 // unbind the callback 721 el.unbind('transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd'); 722 // reset the position 723 setPositionProperty(params['resetValue'], 'reset', 0); 724 // start the loop again 725 tickerLoop(); 726 }); 727 } 728 // use JS animate 729 }else{ 730 var animateObj = {}; 731 animateObj[slider.animProp] = value; 732 if(type == 'slide'){ 733 el.animate(animateObj, duration, slider.settings.easing, function(){ 734 updateAfterSlideTransition(); 735 }); 736 }else if(type == 'reset'){ 737 el.css(slider.animProp, value) 738 }else if(type == 'ticker'){ 739 el.animate(animateObj, speed, 'linear', function(){ 740 setPositionProperty(params['resetValue'], 'reset', 0); 741 // run the recursive loop after animation 742 tickerLoop(); 743 }); 744 } 745 } 746 } 747 748 /** 749 * Populates the pager with proper amount of pages 750 */ 751 var populatePager = function(){ 752 var pagerHtml = ''; 753 var pagerQty = getPagerQty(); 754 // loop through each pager item 755 for(var i=0; i < pagerQty; i++){ 756 var linkContent = ''; 757 // if a buildPager function is supplied, use it to get pager link value, else use index + 1 758 if(slider.settings.buildPager && $.isFunction(slider.settings.buildPager)){ 759 linkContent = slider.settings.buildPager(i); 760 slider.pagerEl.addClass('bx-custom-pager'); 761 }else{ 762 linkContent = i + 1; 763 slider.pagerEl.addClass('bx-default-pager'); 764 } 765 // var linkContent = slider.settings.buildPager && $.isFunction(slider.settings.buildPager) ? slider.settings.buildPager(i) : i + 1; 766 // add the markup to the string 767 pagerHtml += '<div class="bx-pager-item">
vendor: 3,630 bytes, lines 767-849
767<a href="" data-slide-index="' + i + '" class="bx-pager-link">' + linkContent + '</a></div>'; 768 }; 769 // populate the pager element with pager links 770 slider.pagerEl.html(pagerHtml); 771 } 772 773 /** 774 * Appends the pager to the controls element 775 */ 776 var appendPager = function(){ 777 if(!slider.settings.pagerCustom){ 778 // create the pager DOM element 779 slider.pagerEl = $('<div class="bx-pager" />'); 780 // if a pager selector was supplied, populate it with the pager 781 if(slider.settings.pagerSelector){ 782 $(slider.settings.pagerSelector).html(slider.pagerEl); 783 // if no pager selector was supplied, add it after the wrapper 784 }else{ 785 slider.controls.el.addClass('bx-has-pager').append(slider.pagerEl); 786 } 787 // populate the pager 788 populatePager(); 789 }else{ 790 slider.pagerEl = $(slider.settings.pagerCustom); 791 } 792 // assign the pager click binding 793 slider.pagerEl.on('click', 'a', clickPagerBind); 794 } 795 796 /** 797 * Appends prev / next controls to the controls element 798 */ 799 var appendControls = function(){ 800 slider.controls.next = $('<a class="bx-next" href="">' + slider.settings.nextText + '</a>'); 801 slider.controls.prev = $('<a class="bx-prev" href="">' + slider.settings.prevText + '</a>'); 802 // bind click actions to the controls 803 slider.controls.next.bind('click', clickNextBind); 804 slider.controls.prev.bind('click', clickPrevBind); 805 // if nextSlector was supplied, populate it 806 if(slider.settings.nextSelector){ 807 $(slider.settings.nextSelector).append(slider.controls.next); 808 } 809 // if prevSlector was supplied, populate it 810 if(slider.settings.prevSelector){ 811 $(slider.settings.prevSelector).append(slider.controls.prev); 812 } 813 // if no custom selectors were supplied 814 if(!slider.settings.nextSelector && !slider.settings.prevSelector){ 815 // add the controls to the DOM 816 slider.controls.directionEl = $('<div class="bx-controls-direction" />'); 817 // add the control elements to the directionEl 818 slider.controls.directionEl.append(slider.controls.prev).append(slider.controls.next); 819 // slider.viewport.append(slider.controls.directionEl); 820 slider.controls.el.addClass('bx-has-controls-direction').append(slider.controls.directionEl); 821 } 822 } 823 824 /** 825 * Appends start / stop auto controls to the controls element 826 */ 827 var appendControlsAuto = function(){ 828 slider.controls.start = $('<div class="bx-controls-auto-item"><a class="bx-start" href="">' + slider.settings.startText + '</a></div>'); 829 slider.controls.stop = $('<div class="bx-controls-auto-item"><a class="bx-stop" href="">' + slider.settings.stopText + '</a></div>'); 830 // add the controls to the DOM 831 slider.controls.autoEl = $('<div class="bx-controls-auto" />'); 832 // bind click actions to the controls 833 slider.controls.autoEl.on('click', '.bx-start', clickStartBind); 834 slider.controls.autoEl.on('click', '.bx-stop', clickStopBind); 835 // if autoControlsCombine, insert only the "start" control 836 if(slider.settings.autoControlsCombine){ 837 slider.controls.autoEl.append(slider.controls.start); 838 // if autoControlsCombine is false, insert both controls 839 }else{ 840 slider.controls.autoEl.append(slider.controls.start).append(slider.controls.stop); 841 } 842 // if auto controls selector was supplied, populate it with the controls 843 if(slider.settings.autoControlsSelector){ 844 $(slider.settings.autoControlsSelector).html(slider.controls.autoEl); 845 // if auto controls selector was not supplied, add it after the wrapper 846 }else{ 847 slider.controls.el.addClass('bx-has-controls-auto').append(slider.controls.autoEl); 848 } 849 // update the auto controls
850 updateAutoControls(slider.settings.autoStart ? 'stop' : 'start'); 851 } 852 853 /** 854 * Appends image captions to the DOM 855 */ 856 var appendCaptions = function(){ 857 // cycle through each child 858 slider.children.each(function(index){ 859 // get the image title attribute 860 var title = $(this).find('img:first').attr('title'); 861 // append the caption 862 if (title != undefined && ('' + title).length) { 863 $(this).append('<div class="bx-caption"><span>' + title + '</span></div>'); 864 } 865 }); 866 } 867 868 /** 869 * Click next binding 870 * 871 * @param e (event) 872 * - DOM event object 873 */ 874 var clickNextBind = function(e){ 875 // if auto show is running, stop it 876 if (slider.settings.auto) el.stopAuto(); 877 el.goToNextSlide(); 878 e.preventDefault(); 879 } 880 881 /** 882 * Click prev binding 883 * 884 * @param e (event) 885 * - DOM event object 886 */ 887 var clickPrevBind = function(e){ 888 // if auto show is running, stop it 889 if (slider.settings.auto) el.stopAuto(); 890 el.goToPrevSlide(); 891 e.preventDefault(); 892 } 893 894 /** 895 * Click start binding 896 * 897 * @param e (event) 898 * - DOM event object 899 */ 900 var clickStartBind = function(e){ 901 el.startAuto(); 902 e.preventDefault(); 903 } 904 905 /** 906 * Click stop binding 907 * 908 * @param e (event) 909 * - DOM event object 910 */ 911 var clickStopBind = function(e){ 912 el.stopAuto(); 913 e.preventDefault(); 914 } 915 916 /** 917 * Click pager binding 918 * 919 * @param e (event) 920 * - DOM event object 921 */ 922 var clickPagerBind = function(e){ 923 // if auto show is running, stop it 924 if (slider.settings.auto) el.stopAuto(); 925 var pagerLink = $(e.currentTarget); 926 if(pagerLink.attr('data-slide-index') !== undefined){ 927 var pagerIndex = parseInt(pagerLink.attr('data-slide-index')); 928 // if clicked pager link is not active, continue with the goToSlide call 929 if(pagerIndex != slider.active.index) el.goToSlide(pagerIndex); 930 e.preventDefault(); 931 } 932 } 933 934 /** 935 * Updates the pager links with an active class 936 * 937 * @param slideIndex (int) 938 * - index of slide to make active 939 */ 940 var updatePagerActive = function(slideIndex){ 941 // if "short" pager type 942 var len = slider.children.length; // nb of children 943 if(slider.settings.pagerType == 'short'){ 944 if(slider.settings.maxSlides > 1) { 945 len = Math.ceil(slider.children.length/slider.settings.maxSlides); 946 } 947 slider.pagerEl.html( (slideIndex + 1) + slider.settings.pagerShortSeparator + len); 948 return; 949 } 950 // remove all pager active classes 951 slider.pagerEl.find('a').removeClass('active'); 952 // apply the active class for all pagers 953 slider.pagerEl.each(function(i, el) { $(el).find('a').eq(slideIndex).addClass('active'); }); 954 } 955 956 /** 957 * Performs needed actions after a slide transition 958 */ 959 var updateAfterSlideTransition = function(){ 960 // if infinte loop is true 961 if(slider.settings.infiniteLoop){ 962 var position = ''; 963 // first slide 964 if(slider.active.index == 0){ 965 // set the new position 966 position = slider.children.eq(0).position(); 967 // carousel, last slide 968 }else if(slider.active.index == getPagerQty() - 1 && slider.carousel){ 969 position = slider.children.eq((getPagerQty() - 1) * getMoveBy()).position(); 970 // last slide 971 }else if(slider.active.index == slider.children.length - 1){ 972 position = slider.children.eq(slider.children.length - 1).position(); 973 } 974 if(position){ 975 if (slider.settings.mode == 'horizontal') { setPositionProperty(-position.left, 'reset', 0); } 976 else if (slider.settings.mode == 'vertical') { setPositionProperty(-position.top, 'reset', 0); } 977 } 978 } 979 // declare that the transition is complete 980 slider.working = false; 981 // onSlideAfter callback 982 slider.settings.onSlideAfter(slider.children.eq(slider.active.index), slider.oldIndex, slider.active.index); 983 } 984 985 /** 986 * Updates the auto controls state (either active, or combined switch) 987 * 988 * @param state (string) "start", "stop" 989 * - the new state of the auto show 990 */ 991 var updateAutoControls = function(state){ 992 // if autoControlsCombine is true, replace the current control with the new state 993 if(slider.settings.autoControlsCombine){ 994 slider.controls.autoEl.html(slider.controls[state]); 995 // if autoControlsCombine is false, apply the "active" class to the appropriate control 996 }else{ 997 slider.controls.autoEl.find('a').removeClass('active');
998 slider.controls.autoEl.find('a:not(.bx-' + state + ')').addClass('active'); 999 } 1000 } 1001 1002 /** 1003 * Updates the direction controls (checks if either should be hidden) 1004 */ 1005 var updateDirectionControls = function(){ 1006 if(getPagerQty() == 1){ 1007 slider.controls.prev.addClass('disabled'); 1008 slider.controls.next.addClass('disabled'); 1009 }else if(!slider.settings.infiniteLoop && slider.settings.hideControlOnEnd){ 1010 // if first slide 1011 if (slider.active.index == 0){ 1012 slider.controls.prev.addClass('disabled'); 1013 slider.controls.next.removeClass('disabled'); 1014 // if last slide 1015 }else if(slider.active.index == getPagerQty() - 1){ 1016 slider.controls.next.addClass('disabled'); 1017 slider.controls.prev.removeClass('disabled'); 1018 // if any slide in the middle 1019 }else{ 1020 slider.controls.prev.removeClass('disabled'); 1021 slider.controls.next.removeClass('disabled'); 1022 } 1023 } 1024 } 1025 1026 /** 1027 * Initialzes the auto process 1028 */ 1029 var initAuto = function(){ 1030 // if autoDelay was supplied, launch the auto show using a setTimeout() call 1031 if(slider.settings.autoDelay > 0){ 1032 var timeout = setTimeout(el.startAuto, slider.settings.autoDelay); 1033 // if autoDelay was not supplied, start the auto show normally 1034 }else{ 1035 el.startAuto(); 1036 } 1037 // if autoHover is requested 1038 if(slider.settings.autoHover){ 1039 // on el hover 1040 el.hover(function(){ 1041 // if the auto show is currently playing (has an active interval) 1042 if(slider.interval){ 1043 // stop the auto show and pass true agument which will prevent control update 1044 el.stopAuto(true); 1045 // create a new autoPaused value which will be used by the relative "mouseout" event 1046 slider.autoPaused = true; 1047 } 1048 }, function(){ 1049 // if the autoPaused value was created be the prior "mouseover" event 1050 if(slider.autoPaused){ 1051 // start the auto show and pass true agument which will prevent control update 1052 el.startAuto(true); 1053 // reset the autoPaused value 1054 slider.autoPaused = null; 1055 } 1056 }); 1057 } 1058 } 1059 1060 /** 1061 * Initialzes the ticker process 1062 */ 1063 var initTicker = function(){ 1064 var startPosition = 0; 1065 // if autoDirection is "next", append a clone of the entire slider 1066 if(slider.settings.autoDirection == 'next'){ 1067 el.append(slider.children.clone().addClass('bx-clone')); 1068 // if autoDirection is "prev", prepend a clone of the entire slider, and set the left position 1069 }else{ 1070 el.prepend(slider.children.clone().addClass('bx-clone')); 1071 var position = slider.children.first().position(); 1072 startPosition = slider.settings.mode == 'horizontal' ? -position.left : -position.top; 1073 } 1074 setPositionProperty(startPosition, 'reset', 0); 1075 // do not allow controls in ticker mode 1076 slider.settings.pager = false; 1077 slider.settings.controls = false; 1078 slider.settings.autoControls = false; 1079 // if autoHover is requested 1080 if(slider.settings.tickerHover && !slider.usingCSS){ 1081 // on el hover 1082 slider.viewport.hover(function(){ 1083 el.stop(); 1084 }, function(){ 1085 // calculate the total width of children (used to calculate the speed ratio) 1086 var totalDimens = 0; 1087 slider.children.each(function(index){ 1088 totalDimens += slider.settings.mode == 'horizontal' ? $(this).outerWidth(true) : $(this).outerHeight(true); 1089 }); 1090 // calculate the speed ratio (used to determine the new speed to finish the paused animation) 1091 var ratio = slider.settings.speed / totalDimens; 1092 // determine which property to use 1093 var property = slider.settings.mode == 'horizontal' ? 'left' : 'top'; 1094 // calculate the new speed 1095 var newSpeed = ratio * (totalDimens - (Math.abs(parseInt(el.css(property))))); 1096 tickerLoop(newSpeed); 1097 }); 1098 } 1099 // start the ticker loop 1100 tickerLoop(); 1101 } 1102 1103 /** 1104 * Runs a continuous loop, news ticker-style 1105 */ 1106 var tickerLoop = function(resumeSpeed){ 1107 speed = resumeSpeed ? resumeSpeed : slider.settings.speed; 1108 var position = {left: 0, top: 0}; 1109 var reset = {left: 0, top: 0}; 1110 // if "next" animate left position to last child, then reset left to 0 1111 if(slider.settings.autoDirection == 'next'){ 1112 position = el.find('.bx-clone').first().position(); 1113 // if "prev" animate left position to 0, then reset left to first non-clone child 1114 }else{ 1115 reset = slider.children.first().position(); 1116 } 1117 var animateProperty = slider.settings.mode == 'horizontal' ? -position.left : -position.top; 1118 var resetValue = slider.settings.mode == 'horizontal' ? -reset.left : -reset.top; 1119 var params = {resetValue: resetValue}; 1120 setPositionProperty(animateProperty, 'ticker', speed, params); 1121 } 1122 1123 /** 1124 * Initializes touch events 1125 */ 1126 var initTouch = function(){ 1127 // initialize object to contain all touch values 1128 slider.touch = { 1129 start: {x: 0, y: 0}, 1130 end: {x: 0, y: 0} 1131 } 1132 slider.viewport.bind('touchstart', onTouchStart); 1133 } 1134 1135 /** 1136 * Event handler for "touchstart" 1137 * 1138 * @param e (event) 1139 * - DOM event object 1140 */ 1141 var onTouchStart = function(e){ 1142 if(slider.working){ 1143 e.preventDefault(); 1144 }else{ 1145 // record the original position when touch starts 1146 slider.touch.originalPos = el.position(); 1147 var orig = e.originalEvent; 1148 // record the starting touch x, y coordinates
1149 slider.touch.start.x = orig.changedTouches[0].pageX; 1150 slider.touch.start.y = orig.changedTouches[0].pageY; 1151 // bind a "touchmove" event to the viewport 1152 slider.viewport.bind('touchmove', onTouchMove); 1153 // bind a "touchend" event to the viewport 1154 slider.viewport.bind('touchend', onTouchEnd); 1155 } 1156 } 1157 1158 /** 1159 * Event handler for "touchmove" 1160 * 1161 * @param e (event) 1162 * - DOM event object 1163 */ 1164 var onTouchMove = function(e){ 1165 var orig = e.originalEvent; 1166 // if scrolling on y axis, do not prevent default 1167 var xMovement = Math.abs(orig.changedTouches[0].pageX - slider.touch.start.x); 1168 var yMovement = Math.abs(orig.changedTouches[0].pageY - slider.touch.start.y); 1169 // x axis swipe 1170 if((xMovement * 3) > yMovement && slider.settings.preventDefaultSwipeX){ 1171 e.preventDefault(); 1172 // y axis swipe 1173 }else if((yMovement * 3) > xMovement && slider.settings.preventDefaultSwipeY){ 1174 e.preventDefault(); 1175 } 1176 if(slider.settings.mode != 'fade' && slider.settings.oneToOneTouch){ 1177 var value = 0; 1178 // if horizontal, drag along x axis 1179 if(slider.settings.mode == 'horizontal'){ 1180 var change = orig.changedTouches[0].pageX - slider.touch.start.x; 1181 value = slider.touch.originalPos.left + change; 1182 // if vertical, drag along y axis 1183 }else{ 1184 var change = orig.changedTouches[0].pageY - slider.touch.start.y; 1185 value = slider.touch.originalPos.top + change; 1186 } 1187 setPositionProperty(value, 'reset', 0); 1188 } 1189 } 1190 1191 /** 1192 * Event handler for "touchend" 1193 * 1194 * @param e (event) 1195 * - DOM event object 1196 */ 1197 var onTouchEnd = function(e){ 1198 slider.viewport.unbind('touchmove', onTouchMove); 1199 var orig = e.originalEvent; 1200 var value = 0; 1201 // record end x, y positions 1202 slider.touch.end.x = orig.changedTouches[0].pageX; 1203 slider.touch.end.y = orig.changedTouches[0].pageY; 1204 // if fade mode, check if absolute x distance clears the threshold 1205 if(slider.settings.mode == 'fade'){ 1206 var distance = Math.abs(slider.touch.start.x - slider.touch.end.x); 1207 if(distance >= slider.settings.swipeThreshold){ 1208 slider.touch.start.x > slider.touch.end.x ? el.goToNextSlide() : el.goToPrevSlide(); 1209 el.stopAuto(); 1210 } 1211 // not fade mode 1212 }else{ 1213 var distance = 0; 1214 // calculate distance and el's animate property 1215 if(slider.settings.mode == 'horizontal'){ 1216 distance = slider.touch.end.x - slider.touch.start.x; 1217 value = slider.touch.originalPos.left; 1218 }else{ 1219 distance = slider.touch.end.y - slider.touch.start.y; 1220 value = slider.touch.originalPos.top; 1221 } 1222 // if not infinite loop and first / last slide, do not attempt a slide transition 1223 if(!slider.settings.infiniteLoop && ((slider.active.index == 0 && distance > 0) || (slider.active.last && distance < 0))){ 1224 setPositionProperty(value, 'reset', 200); 1225 }else{ 1226 // check if distance clears threshold 1227 if(Math.abs(distance) >= slider.settings.swipeThreshold){ 1228 distance < 0 ? el.goToNextSlide() : el.goToPrevSlide(); 1229 el.stopAuto(); 1230 }else{ 1231 // el.animate(property, 200); 1232 setPositionProperty(value, 'reset', 200); 1233 } 1234 } 1235 } 1236 slider.viewport.unbind('touchend', onTouchEnd); 1237 } 1238 1239 /** 1240 * Window resize event callback 1241 */ 1242 var resizeWindow = function(e){ 1243 // don't do anything if slider isn't initialized. 1244 if(!slider.initialized) return; 1245 // get the new window dimens (again, thank you IE) 1246 var windowWidthNew = $(window).width(); 1247 var windowHeightNew = $(window).height(); 1248 // make sure that it is a true window resize 1249 // *we must check this because our dinosaur friend IE fires a window resize event when certain DOM elements 1250 // are resized. Can you just die already?* 1251 if(windowWidth != windowWidthNew || windowHeight != windowHeightNew){ 1252 // set the new window dimens 1253 windowWidth = windowWidthNew; 1254 windowHeight = windowHeightNew; 1255 // update all dynamic elements 1256 el.redrawSlider(); 1257 // Call user resize handler 1258 slider.settings.onSliderResize.call(el, slider.active.index); 1259 } 1260 } 1261 1262 /** 1263 * =================================================================================== 1264 * = PUBLIC FUNCTIONS 1265 * =================================================================================== 1266 */ 1267 1268 /** 1269 * Performs slide transition to the specified slide 1270 * 1271 * @param slideIndex (int) 1272 * - the destination slide's index (zero-based) 1273 * 1274 * @param direction (string) 1275 * - INTERNAL USE ONLY - the direction of travel ("prev" / "next") 1276 */ 1277 el.goToSlide = function(slideIndex, direction){ 1278 // if plugin is currently in motion, ignore request 1279 if(slider.working || slider.active.index == slideIndex) return; 1280 // declare that plugin is in motion 1281 slider.working = true; 1282 // store the old index 1283 slider.oldIndex = slider.active.index; 1284 // if slideIndex is less than zero, set active index to last child (this happens during infinite loop) 1285 if(slideIndex < 0){ 1286 slider.active.index = getPagerQty() - 1; 1287 // if slideIndex is greater than children length, set active index to 0 (this happens during infinite loop) 1288 }else if(slideIndex >= getPagerQty()){ 1289 slider.active.index = 0; 1290 // set active index to requested slide 1291 }else{ 1292 slider.active.index = slideIndex; 1293 } 1294 // onSlideBefore, onSlideNext, onSlidePrev callbacks 1295 slider.settings.onSlideBefore(slider.children.eq(slider.active.index), slider.oldIndex, slider.active.index); 1296 if(direction == 'next'){ 1297 slider.settings.onSlideNext(slider.children.eq(slider.active.index), slider.oldIndex, slider.active.index); 1298 }else if(direction == 'prev'){ 1299 slider.settings.onSlidePrev(slider.children.eq(slider.active.index), slider.oldIndex, slider.active.index); 1300 } 1301 // check if last slide 1302 slider.active.last = slider.active.index >= getPagerQty() - 1; 1303 // update the pager with active class 1304 if(slider.settings.pager) updatePagerActive(slider.active.index); 1305 // // check for direction control update 1306 if(slider.settings.controls) updateDirectionControls(); 1307 // if slider is set to mode: "fade" 1308 if(slider.settings.mode == 'fade'){ 1309 // if adaptiveHeight is true and next height is different from current height, animate to the new height 1310 if(slider.settings.adaptiveHeight && slider.viewport.height() != getViewportHe
1310ight()){ 1311 slider.viewport.animate({height: getViewportHeight()}, slider.settings.adaptiveHeightSpeed); 1312 } 1313 // fade out the visible child and reset its z-index value 1314 slider.children.filter(':visible').fadeOut(slider.settings.speed).css({zIndex: 0}); 1315 // fade in the newly requested slide 1316 slider.children.eq(slider.active.index).css('zIndex', slider.settings.slideZIndex+1).fadeIn(slider.settings.speed, function(){ 1317 $(this).css('zIndex', slider.settings.slideZIndex); 1318 updateAfterSlideTransition(); 1319 }); 1320 // slider mode is not "fade" 1321 }else{ 1322 // if adaptiveHeight is true and next height is different from current height, animate to the new height 1323 if(slider.settings.adaptiveHeight && slider.viewport.height() != getViewportHeight()){ 1324 slider.viewport.animate({height: getViewportHeight()}, slider.settings.adaptiveHeightSpeed); 1325 } 1326 var moveBy = 0; 1327 var position = {left: 0, top: 0}; 1328 // if carousel and not infinite loop 1329 if(!slider.settings.infiniteLoop && slider.carousel && slider.active.last){ 1330 if(slider.settings.mode == 'horizontal'){ 1331 // get the last child position 1332 var lastChild = slider.children.eq(slider.children.length - 1); 1333 position = lastChild.position(); 1334 // calculate the position of the last slide 1335 moveBy = slider.viewport.width() - lastChild.outerWidth(); 1336 }else{ 1337 // get last showing index position 1338 var lastShowingIndex = slider.children.length - slider.settings.minSlides; 1339 position = slider.children.eq(lastShowingIndex).position(); 1340 } 1341 // horizontal carousel, going previous while on first slide (infiniteLoop mode) 1342 }else if(slider.carousel && slider.active.last && direction == 'prev'){ 1343 // get the last child position 1344 var eq = slider.settings.moveSlides == 1 ? slider.settings.maxSlides - getMoveBy() : ((getPagerQty() - 1) * getMoveBy()) - (slider.children.length - slider.settings.maxSlides); 1345 var lastChild = el.children('.bx-clone').eq(eq); 1346 position = lastChild.position(); 1347 // if infinite loop and "Next" is clicked on the last slide 1348 }else if(direction == 'next' && slider.active.index == 0){ 1349 // get the last clone position 1350 position = el.find('> .bx-clone').eq(slider.settings.maxSlides).position(); 1351 slider.active.last = false; 1352 // normal non-zero requests 1353 }else if(slideIndex >= 0){ 1354 var requestEl = slideIndex * getMoveBy(); 1355 position = slider.children.eq(requestEl).position(); 1356 } 1357 1358 /* If the position doesn't exist 1359 * (e.g. if you destroy the slider on a next click), 1360 * it doesn't throw an error. 1361 */ 1362 if ("undefined" !== typeof(position)) { 1363 var value = slider.settings.mode == 'horizontal' ? -(position.left - moveBy) : -position.top; 1364 // plugin values to be animated 1365 setPositionProperty(value, 'slide', slider.settings.speed); 1366 } 1367 } 1368 } 1369 1370 /** 1371 * Transitions to the next slide in the show 1372 */ 1373 el.goToNextSlide = function(){ 1374 // if infiniteLoop is false and last page is showing, disregard call 1375 if (!slider.settings.infiniteLoop && slider.active.last) return; 1376 var pagerIndex = parseInt(slider.active.index) + 1; 1377 el.goToSlide(pagerIndex, 'next'); 1378 } 1379 1380 /** 1381 * Transitions to the prev slide in the show 1382 */ 1383 el.goToPrevSlide = function(){ 1384 // if infiniteLoop is false and last page is showing, disregard call 1385 if (!slider.settings.infiniteLoop && slider.active.index == 0) return; 1386 var pagerIndex = parseInt(slider.active.index) - 1; 1387 el.goToSlide(pagerIndex, 'prev'); 1388 } 1389 1390 /** 1391 * Starts the auto show 1392 * 1393 * @param preventControlUpdate (boolean) 1394 * - if true, auto controls state will not be updated 1395 */ 1396 el.startAuto = function(preventControlUpdate){ 1397 // if an interval already exists, disregard call 1398 if(slider.interval) return; 1399 // create an interval 1400 slider.interval = setInterval(function(){ 1401 slider.settings.autoDirection == 'next' ? el.goToNextSlide() : el.goToPrevSlide(); 1402 }, slider.settings.pause); 1403 // if auto controls are displayed and preventControlUpdate is not true 1404 if (slider.settings.autoControls && preventControlUpdate != true) updateAutoControls('stop'); 1405 } 1406 1407 /** 1408 * Stops the auto show 1409 * 1410 * @param preventControlUpdate (boolean) 1411 * - if true, auto controls state will not be updated 1412 */ 1413 el.stopAuto = function(preventControlUpdate){ 1414 // if no interval exists, disregard call
1415 if(!slider.interval) return; 1416 // clear the interval 1417 clearInterval(slider.interval); 1418 slider.interval = null; 1419 // if auto controls are displayed and preventControlUpdate is not true 1420 if (slider.settings.autoControls && preventControlUpdate != true) updateAutoControls('start'); 1421 } 1422 1423 /** 1424 * Returns current slide index (zero-based) 1425 */ 1426 el.getCurrentSlide = function(){ 1427 return slider.active.index; 1428 } 1429 1430 /** 1431 * Returns current slide element 1432 */ 1433 el.getCurrentSlideElement = function(){ 1434 return slider.children.eq(slider.active.index); 1435 } 1436 1437 /** 1438 * Returns number of slides in show 1439 */ 1440 el.getSlideCount = function(){ 1441 return slider.children.length; 1442 } 1443 1444 /** 1445 * Update all dynamic slider elements 1446 */ 1447 el.redrawSlider = function(){ 1448 // resize all children in ratio to new screen size 1449 slider.children.add(el.find('.bx-clone')).width(calcSlideWidthidth()); 1450 // adjust the height 1451 slider.viewport.css('height', getViewportHeight()); 1452 // update the slide position 1453 if(!slider.settings.ticker) setSlidePosition(); 1454 // if active.last was true before the screen resize, we want 1455 // to keep it last no matter what screen size we end on 1456 if (slider.active.last) slider.active.index = getPagerQty() - 1; 1457 // if the active index (page) no longer exists due to the resize, simply set the index as last 1458 if (slider.active.index >= getPagerQty()) slider.active.last = true; 1459 // if a pager is being displayed and a custom pager is not being used, update it 1460 if(slider.settings.pager && !slider.settings.pagerCustom){ 1461 populatePager(); 1462 updatePagerActive(slider.active.index); 1463 } 1464 } 1465 1466 /** 1467 * Destroy the current instance of the slider (revert everything back to original state) 1468 */ 1469 el.destroySlider = function(){ 1470 // don't do anything if slider has already been destroyed 1471 if(!slider.initialized) return; 1472 slider.initialized = false; 1473 $('.bx-clone', this).remove(); 1474 slider.children.each(function() { 1475 $(this).data("origStyle") != undefined ? $(this).attr("style", $(this).data("origStyle")) : $(this).removeAttr('style'); 1476 }); 1477 $(this).data("origStyle") != undefined ? this.attr("style", $(this).data("origStyle")) : $(this).removeAttr('style'); 1478 $(this).unwrap().unwrap(); 1479 if(slider.controls.el) slider.controls.el.remove(); 1480 if(slider.controls.next) slider.controls.next.remove(); 1481 if(slider.controls.prev) slider.controls.prev.remove(); 1482 if(slider.pagerEl && slider.settings.controls) slider.pagerEl.remove(); 1483 $('.bx-caption', this).remove(); 1484 if(slider.controls.autoEl) slider.controls.autoEl.remove(); 1485 clearInterval(slider.interval); 1486 if(slider.settings.responsive) $(window).unbind('resize', resizeWindow); 1487 } 1488 1489 /** 1490 * Reload the slider (revert all DOM changes, and re-initialize) 1491 */ 1492 el.reloadSlider = function(settings){ 1493 if (settings != undefined) options = settings; 1494 el.destroySlider(); 1495 init(); 1496 } 1497 1498 /** 1499 * auto reload functionality 1500 */ 1501 $(window).resize(function() { 1502 if(slider.settings.autoReload) { 1503 el.reloadSlider(); 1504 } 1505 }); 1506 1507 init(); 1508 1509 // returns the current jQuery object 1510 return this; 1511 } 1512 1513})(jQuery); 1514 1515 /** 1516 * Self calling functionality 1517 * --------------------------------------------------------------------------------------- */ 1518 1519 // $('[data-call="bxslider"]').each(function() { 1520 // $(this).bxSlider(); 1521 // }); 1522 1523 1524 1525/* 1526 * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/ 1527 * 1528 * Uses the built in easing capabilities added In jQuery 1.1 1529 * to offer multiple easing options 1530 * 1531 * TERMS OF USE - jQuery Easing 1532 * 1533 * Open source under the BSD License. 1534 * 1535 * Copyright © 2008 George McGinley Smith 1536 * All rights reserved. 1537 * 1538 * Redistribution and use in source and binary forms, with or without modification, 1539 * are permitted provided that the following conditions are met: 1540 * 1541 * Redistributions of source code must retain the above copyright notice, this list of 1542 * conditions and the following disclaimer. 1543 * Redistributions in binary form must reproduce the above copyright notice, this list 1544 * of conditions and the following disclaimer in the documentation and/or other materials 1545 * provided with the distribution. 1546 * 1547 * Neither the name of the author nor the names of contributors may be used to endorse 1548 * or promote products derived from this software without specific prior written permission. 1549 * 1550 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 1551 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 1552 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 1553 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
vendor: 5,091 bytes, lines 1554-1699
1554 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 1555 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 1556 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 1557 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 1558 * OF THE POSSIBILITY OF SUCH DAMAGE. 1559 * 1560*/ 1561 1562// t: current time, b: begInnIng value, c: change In value, d: duration 1563jQuery.easing['jswing'] = jQuery.easing['swing']; 1564 1565jQuery.extend( jQuery.easing, 1566{ 1567 def: 'easeOutQuad', 1568 swing: function (x, t, b, c, d) { 1569 //alert(jQuery.easing.default); 1570 return jQuery.easing[jQuery.easing.def](x, t, b, c, d); 1571 }, 1572 easeInQuad: function (x, t, b, c, d) { 1573 return c*(t/=d)*t + b; 1574 }, 1575 easeOutQuad: function (x, t, b, c, d) { 1576 return -c *(t/=d)*(t-2) + b; 1577 }, 1578 easeInOutQuad: function (x, t, b, c, d) { 1579 if ((t/=d/2) < 1) return c/2*t*t + b; 1580 return -c/2 * ((--t)*(t-2) - 1) + b; 1581 }, 1582 easeInCubic: function (x, t, b, c, d) { 1583 return c*(t/=d)*t*t + b; 1584 }, 1585 easeOutCubic: function (x, t, b, c, d) { 1586 return c*((t=t/d-1)*t*t + 1) + b; 1587 }, 1588 easeInOutCubic: function (x, t, b, c, d) { 1589 if ((t/=d/2) < 1) return c/2*t*t*t + b; 1590 return c/2*((t-=2)*t*t + 2) + b; 1591 }, 1592 easeInQuart: function (x, t, b, c, d) { 1593 return c*(t/=d)*t*t*t + b; 1594 }, 1595 easeOutQuart: function (x, t, b, c, d) { 1596 return -c * ((t=t/d-1)*t*t*t - 1) + b; 1597 }, 1598 easeInOutQuart: function (x, t, b, c, d) { 1599 if ((t/=d/2) < 1) return c/2*t*t*t*t + b; 1600 return -c/2 * ((t-=2)*t*t*t - 2) + b; 1601 }, 1602 easeInQuint: function (x, t, b, c, d) { 1603 return c*(t/=d)*t*t*t*t + b; 1604 }, 1605 easeOutQuint: function (x, t, b, c, d) { 1606 return c*((t=t/d-1)*t*t*t*t + 1) + b; 1607 }, 1608 easeInOutQuint: function (x, t, b, c, d) { 1609 if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b; 1610 return c/2*((t-=2)*t*t*t*t + 2) + b; 1611 }, 1612 easeInSine: function (x, t, b, c, d) { 1613 return -c * Math.cos(t/d * (Math.PI/2)) + c + b; 1614 }, 1615 easeOutSine: function (x, t, b, c, d) { 1616 return c * Math.sin(t/d * (Math.PI/2)) + b; 1617 }, 1618 easeInOutSine: function (x, t, b, c, d) { 1619 return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b; 1620 }, 1621 easeInExpo: function (x, t, b, c, d) { 1622 return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b; 1623 }, 1624 easeOutExpo: function (x, t, b, c, d) { 1625 return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b; 1626 }, 1627 easeInOutExpo: function (x, t, b, c, d) { 1628 if (t==0) return b; 1629 if (t==d) return b+c; 1630 if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b; 1631 return c/2 * (-Math.pow(2, -10 * --t) + 2) + b; 1632 }, 1633 easeInCirc: function (x, t, b, c, d) { 1634 return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b; 1635 }, 1636 easeOutCirc: function (x, t, b, c, d) { 1637 return c * Math.sqrt(1 - (t=t/d-1)*t) + b; 1638 }, 1639 easeInOutCirc: function (x, t, b, c, d) { 1640 if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b; 1641 return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b; 1642 }, 1643 easeInElastic: function (x, t, b, c, d) { 1644 var s=1.70158;var p=0;var a=c; 1645 if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3; 1646 if (a < Math.abs(c)) { a=c; var s=p/4; } 1647 else var s = p/(2*Math.PI) * Math.asin (c/a); 1648 return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b; 1649 }, 1650 easeOutElastic: function (x, t, b, c, d) { 1651 var s=1.70158;var p=0;var a=c; 1652 if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3; 1653 if (a < Math.abs(c)) { a=c; var s=p/4; } 1654 else var s = p/(2*Math.PI) * Math.asin (c/a); 1655 return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b; 1656 }, 1657 easeInOutElastic: function (x, t, b, c, d) { 1658 var s=1.70158;var p=0;var a=c; 1659 if (t==0) return b; if ((t/=d/2)==2) return b+c; if (!p) p=d*(.3*1.5); 1660 if (a < Math.abs(c)) { a=c; var s=p/4; } 1661 else var s = p/(2*Math.PI) * Math.asin (c/a); 1662 if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b; 1663 return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b; 1664 }, 1665 easeInBack: function (x, t, b, c, d, s) { 1666 if (s == undefined) s = 1.70158; 1667 return c*(t/=d)*t*((s+1)*t - s) + b; 1668 }, 1669 easeOutBack: function (x, t, b, c, d, s) { 1670 if (s == undefined) s = 1.70158; 1671 return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b; 1672 }, 1673 easeInOutBack: function (x, t, b, c, d, s) { 1674 if (s == undefined) s = 1.70158; 1675 if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b; 1676 return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b; 1677 }, 1678 easeInBounce: function (x, t, b, c, d) { 1679 return c - jQuery.easing.easeOutBounce (x, d-t, 0, c, d) + b; 1680 }, 1681 easeOutBounce: function (x, t, b, c, d) { 1682 if ((t/=d) < (1/2.75)) { 1683 return c*(7.5625*t*t) + b; 1684 } else if (t < (2/2.75)) { 1685 return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b; 1686 } else if (t < (2.5/2.75)) { 1687 return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b; 1688 } else { 1689 return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b; 1690 } 1691 }, 1692 easeInOutBounce: function (x, t, b, c, d) { 1693 if (t < d/2) return jQuery.easing.easeInBounce (x, t*2, 0, c, d) * .5 + b; 1694 return jQuery.easing.easeOutBounce (x, t*2-d, 0, c, d) * .5 + c*.5 + b; 1695 } 1696}); 1697 1698/* 1699 *
1700 * TERMS OF USE - EASING EQUATIONS 1701 * 1702 * Open source under the BSD License. 1703 * 1704 * Copyright © 2001 Robert Penner 1705 * All rights reserved. 1706 * 1707 * Redistribution and use in source and binary forms, with or without modification, 1708 * are permitted provided that the following conditions are met: 1709 * 1710 * Redistributions of source code must retain the above copyright notice, this list of 1711 * conditions and the following disclaimer. 1712 * Redistributions in binary form must reproduce the above copyright notice, this list 1713 * of conditions and the following disclaimer in the documentation and/or other materials 1714 * provided with the distribution. 1715 * 1716 * Neither the name of the author nor the names of contributors may be used to endorse 1717 * or promote products derived from this software without specific prior written permission. 1718 * 1719 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 1720 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 1721 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 1722 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 1723 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 1724 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 1725 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 1726 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 1727 * OF THE POSSIBILITY OF SUCH DAMAGE. 1728 * 1729 */
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.