/** * jquery bxslider v3.0 * http://bxslider.com * * copyright 2011, steven wanderski * http://bxcreative.com * * free to use and abuse under the mit license. * http://www.opensource.org/licenses/mit-license.php * */ (function($){ $.fn.bxslider = function(options){ var defaults = { mode: 'horizontal', // 'horizontal', 'vertical', 'fade' childselector: '', // jquery selector - elements to be used as slides infiniteloop: true, // true, false - display first slide after last hidecontrolonend: false, // true, false - if true, will hide 'next' control on last slide and 'prev' control on first controls: true, // true, false - previous and next controls speed: 500, // integer - in ms, duration of time slide transitions will occupy easing: 'swing', // used with jquery.easing.1.3.js - see http://gsgd.co.uk/sandbox/jquery/easing/ for available options pager: false, // true / false - display a pager pagerselector: null, // jquery selector - element to contain the pager. ex: '#pager' pagertype: 'full', // 'full', 'short' - if 'full' pager displays 1,2,3... if 'short' pager displays 1 / 4 pagerlocation: 'bottom', // 'bottom', 'top' - location of pager pagershortseparator: '/', // string - ex: 'of' pager would display 1 of 4 pageractiveclass: 'pager-active', // string - classname attached to the active pager link nexttext: 'next', // string - text displayed for 'next' control nextimage: '', // string - filepath of image used for 'next' control. ex: 'images/next.jpg' nextselector: null, // jquery selector - element to contain the next control. ex: '#next' prevtext: 'prev', // string - text displayed for 'previous' control previmage: '', // string - filepath of image used for 'previous' control. ex: 'images/prev.jpg' prevselector: null, // jquery selector - element to contain the previous control. ex: '#next' captions: false, // true, false - display image captions (reads the image 'title' tag) captionsselector: null, // jquery selector - element to contain the captions. ex: '#captions' auto: false, // true, false - make slideshow change automatically autodirection: 'next', // 'next', 'prev' - direction in which auto show will traverse autocontrols: false, // true, false - show 'start' and 'stop' controls for auto show autocontrolsselector: null, // jquery selector - element to contain the auto controls. ex: '#auto-controls' autostart: true, // true, false - if false show will wait for 'start' control to activate autohover: false, // true, false - if true show will pause on mouseover autodelay: 0, // integer - in ms, the amount of time before starting the auto show pause: 3000, // integer - in ms, the duration between each slide transition starttext: 'start', // string - text displayed for 'start' control startimage: '', // string - filepath of image used for 'start' control. ex: 'images/start.jpg' stoptext: 'stop', // string - text displayed for 'stop' control stopimage: '', // string - filepath of image used for 'stop' control. ex: 'images/stop.jpg' ticker: false, // true, false - continuous motion ticker mode (think news ticker) // note: autocontrols, autocontrolsselector, and autohover apply to ticker! tickerspeed: 5000, // float - use value between 1 and 5000 to determine ticker speed - the smaller the value the faster the ticker speed tickerdirection: 'next', // 'next', 'prev' - direction in which ticker show will traverse tickerhover: false, // true, false - if true ticker will pause on mouseover wrapperclass: 'bx-wrapper', // string - classname attached to the slider wraper startingslide: 0, // integer - show will start on specified slide. note: slides are zero based! displayslideqty: 1, // integer - number of slides to display at once moveslideqty: 1, // integer - number of slides to move at once randomstart: false, // true, false - if true show will start on a random slide onbeforeslide: function(){}, // function(currentslidenumber, totalslideqty, currentslidehtmlobject) - advanced use only! see the tutorial here: http://bxslider.com/custom-pager onafterslide: function(){}, // function(currentslidenumber, totalslideqty, currentslidehtmlobject) - advanced use only! see the tutorial here: http://bxslider.com/custom-pager onlastslide: function(){}, // function(currentslidenumber, totalslideqty, currentslidehtmlobject) - advanced use only! see the tutorial here: http://bxslider.com/custom-pager onfirstslide: function(){}, // function(currentslidenumber, totalslideqty, currentslidehtmlobject) - advanced use only! see the tutorial here: http://bxslider.com/custom-pager onnextslide: function(){}, // function(currentslidenumber, totalslideqty, currentslidehtmlobject) - advanced use only! see the tutorial here: http://bxslider.com/custom-pager onprevslide: function(){}, // function(currentslidenumber, totalslideqty, currentslidehtmlobject) - advanced use only! see the tutorial here: http://bxslider.com/custom-pager buildpager: null // function(slideindex, slidehtmlobject){ return string; } - advanced use only! see the tutorial here: http://bxslider.com/custom-pager } var options = $.extend(defaults, options); // cache the base element var base = this; // initialize (and localize) all variables var $parent = ''; var $origelement = ''; var $children = ''; var $outerwrapper = ''; var $firstchild = ''; var childrenwidth = ''; var childrenouterwidth = ''; var wrapperwidth = ''; var wrapperheight = ''; var $pager = ''; var interval = ''; var $autocontrols = ''; var $stophtml = ''; var $startcontent = ''; var $stopcontent = ''; var autoplaying = true; var loaded = false; var childrenmaxwidth = 0; var childrenmaxheight = 0; var currentslide = 0; var origleft = 0; var origtop = 0; var origshowwidth = 0; var origshowheight = 0; var tickerleft = 0; var tickertop = 0; var isworking = false; var firstslide = 0; var lastslide = $children.length - 1; // public functions /** * go to specified slide */ this.gotoslide = function(number, stopauto){ if(!isworking){ isworking = true; // set current slide to argument currentslide = number; options.onbeforeslide(currentslide, $children.length, $children.eq(currentslide)); // check if stopauto argument is supplied if(typeof(stopauto) == 'undefined'){ var stopauto = true; } if(stopauto){ // if show is auto playing, stop it if(options.auto){ base.stopshow(true); } } slide = number; // check for first slide callback if(slide == firstslide){ options.onfirstslide(currentslide, $children.length, $children.eq(currentslide)); } // check for last slide callback if(slide == lastslide){ options.onlastslide(currentslide, $children.length, $children.eq(currentslide)); } // horizontal if(options.mode == 'horizontal'){ $parent.animate({'left': '-'+getslideposition(slide, 'left')+'px'}, options.speed, options.easing, function(){ isworking = false; // perform the callback function options.onafterslide(currentslide, $children.length, $children.eq(currentslide)); }); // vertical }else if(options.mode == 'vertical'){ $parent.animate({'top': '-'+getslideposition(slide, 'top')+'px'}, options.speed, options.easing, function(){ isworking = false; // perform the callback function options.onafterslide(currentslide, $children.length, $children.eq(currentslide)); }); // fade }else if(options.mode == 'fade'){ setchildrenfade(); } // check to remove controls on last/first slide checkendcontrols(); // accomodate multi slides if(options.moveslideqty > 1){ number = math.floor(number / options.moveslideqty); } // make the current slide active makeslideactive(number); // display the caption showcaptions(); } } /** * go to next slide */ this.gotonextslide = function(stopauto){ // check if stopauto argument is supplied if(typeof(stopauto) == 'undefined'){ var stopauto = true; } if(stopauto){ // if show is auto playing, stop it if(options.auto){ base.stopshow(true); } } // makes slideshow finite if(!options.infiniteloop){ if(!isworking){ var slideloop = false; // make current slide the old value plus moveslideqty currentslide = (currentslide + (options.moveslideqty)); // if current slide has looped on itself if(currentslide <= lastslide){ checkendcontrols(); // next slide callback options.onnextslide(currentslide, $children.length, $children.eq(currentslide)); // move to appropriate slide base.gotoslide(currentslide); }else{ currentslide -= options.moveslideqty; } } // end if(!isworking) }else{ if(!isworking){ isworking = true; var slideloop = false; // make current slide the old value plus moveslideqty currentslide = (currentslide + options.moveslideqty); // if current slide has looped on itself if(currentslide > lastslide){ currentslide = currentslide % $children.length; slideloop = true; } // next slide callback options.onnextslide(currentslide, $children.length, $children.eq(currentslide)); // slide before callback options.onbeforeslide(currentslide, $children.length, $children.eq(currentslide)); if(options.mode == 'horizontal'){ // get the new 'left' property for $parent var parentleft = (options.moveslideqty * childrenouterwidth); // animate to the new 'left' $parent.animate({'left': '-='+parentleft+'px'}, options.speed, options.easing, function(){ isworking = false; // if its time to loop, reset the $parent if(slideloop){ $parent.css('left', '-'+getslideposition(currentslide, 'left')+'px'); } // perform the callback function options.onafterslide(currentslide, $children.length, $children.eq(currentslide)); }); }else if(options.mode == 'vertical'){ // get the new 'left' property for $parent var parenttop = (options.moveslideqty * childrenmaxheight); // animate to the new 'left' $parent.animate({'top': '-='+parenttop+'px'}, options.speed, options.easing, function(){ isworking = false; // if its time to loop, reset the $parent if(slideloop){ $parent.css('top', '-'+getslideposition(currentslide, 'top')+'px'); } // perform the callback function options.onafterslide(currentslide, $children.length, $children.eq(currentslide)); }); }else if(options.mode == 'fade'){ setchildrenfade(); } // make the current slide active if(options.moveslideqty > 1){ makeslideactive(math.ceil(currentslide / options.moveslideqty)); }else{ makeslideactive(currentslide); } // display the caption showcaptions(); } // end if(!isworking) } } // end function /** * go to previous slide */ this.gotopreviousslide = function(stopauto){ // check if stopauto argument is supplied if(typeof(stopauto) == 'undefined'){ var stopauto = true; } if(stopauto){ // if show is auto playing, stop it if(options.auto){ base.stopshow(true); } } // makes slideshow finite if(!options.infiniteloop){ if(!isworking){ var slideloop = false; // make current slide the old value plus moveslideqty currentslide = currentslide - options.moveslideqty; // if current slide has looped on itself if(currentslide < 0){ currentslide = 0; // if specified, hide the control on the last slide if(options.hidecontrolonend){ $outerwrapper.children('.bx-prev').hide(); } } checkendcontrols(); // next slide callback options.onprevslide(currentslide, $children.length, $children.eq(currentslide)); // move to appropriate slide base.gotoslide(currentslide); } }else{ if(!isworking){ isworking = true; var slideloop = false; // make current slide the old value plus moveslideqty currentslide = (currentslide - (options.moveslideqty)); // if current slide has looped on itself if(currentslide < 0){ negativeoffset = (currentslide % $children.length); if(negativeoffset == 0){ currentslide = 0; }else{ currentslide = ($children.length) + negativeoffset; } slideloop = true; } // next slide callback options.onprevslide(currentslide, $children.length, $children.eq(currentslide)); // slide before callback options.onbeforeslide(currentslide, $children.length, $children.eq(currentslide)); if(options.mode == 'horizontal'){ // get the new 'left' property for $parent var parentleft = (options.moveslideqty * childrenouterwidth); // animate to the new 'left' $parent.animate({'left': '+='+parentleft+'px'}, options.speed, options.easing, function(){ isworking = false; // if its time to loop, reset the $parent if(slideloop){ $parent.css('left', '-'+getslideposition(currentslide, 'left')+'px'); } // perform the callback function options.onafterslide(currentslide, $children.length, $children.eq(currentslide)); }); }else if(options.mode == 'vertical'){ // get the new 'left' property for $parent var parenttop = (options.moveslideqty * childrenmaxheight); // animate to the new 'left' $parent.animate({'top': '+='+parenttop+'px'}, options.speed, options.easing, function(){ isworking = false; // if its time to loop, reset the $parent if(slideloop){ $parent.css('top', '-'+getslideposition(currentslide, 'top')+'px'); } // perform the callback function options.onafterslide(currentslide, $children.length, $children.eq(currentslide)); }); }else if(options.mode == 'fade'){ setchildrenfade(); } // make the current slide active if(options.moveslideqty > 1){ makeslideactive(math.ceil(currentslide / options.moveslideqty)); }else{ makeslideactive(currentslide); } // display the caption showcaptions(); } // end if(!isworking) } } // end function /** * go to first slide */ this.gotofirstslide = function(stopauto){ // check if stopauto argument is supplied if(typeof(stopauto) == 'undefined'){ var stopauto = true; } base.gotoslide(firstslide, stopauto); } /** * go to last slide */ this.gotolastslide = function(){ // check if stopauto argument is supplied if(typeof(stopauto) == 'undefined'){ var stopauto = true; } base.gotoslide(lastslide, stopauto); } /** * get the current slide */ this.getcurrentslide = function(){ return currentslide; } /** * get the total slide count */ this.getslidecount = function(){ return $children.length; } /** * suspend the slideshow */ this.suspendshow = function(changetext){ clearinterval(interval); // check if changetext argument is supplied if(typeof(changetext) == 'undefined'){ var changetext = true; } if(changetext && options.autocontrols){ $autocontrols.html($startcontent).removeclass('stop').addclass('start'); } } /** * restart the suspended slideshow */ this.restartshow = function(changetext){ // check if changetext argument is supplied if(typeof(changetext) == 'undefined'){ var changetext = true; } if(autoplaying){ setautointerval(); } if(changetext && options.autocontrols){ $autocontrols.html($stopcontent).removeclass('start').addclass('stop'); } } /** * stop the slideshow permanently */ this.stopshow = function(changetext){ autoplaying = false; this.suspendshow(changetext); } /** * start the slideshow */ this.startshow = function(changetext){ autoplaying = true; this.restartshow(changetext); } /** * stops the ticker */ this.stopticker = function(changetext){ $parent.stop(); // check if changetext argument is supplied if(typeof(changetext) == 'undefined'){ var changetext = true; } if(changetext && options.ticker){ $autocontrols.html($startcontent).removeclass('stop').addclass('start'); autoplaying = false; } } /** * starts the ticker */ this.startticker = function(changetext){ if(options.mode == 'horizontal'){ if(options.tickerdirection == 'next'){ // get the 'left' property where the ticker stopped var stoppedleft = parseint($parent.css('left')); // calculate the remaining distance the show must travel until the loop var remainingdistance = (origshowwidth + stoppedleft) + $children.eq(0).width(); }else if(options.tickerdirection == 'prev'){ // get the 'left' property where the ticker stopped var stoppedleft = -parseint($parent.css('left')); // calculate the remaining distance the show must travel until the loop var remainingdistance = (stoppedleft) - $children.eq(0).width(); } // calculate the speed ratio to seamlessly finish the loop var finishingspeed = (remainingdistance * options.tickerspeed) / origshowwidth; // call the show movetheshow(tickerleft, remainingdistance, finishingspeed); }else if(options.mode == 'vertical'){ if(options.tickerdirection == 'next'){ // get the 'top' property where the ticker stopped var stoppedtop = parseint($parent.css('top')); // calculate the remaining distance the show must travel until the loop var remainingdistance = (origshowheight + stoppedtop) + $children.eq(0).height(); }else if(options.tickerdirection == 'prev'){ // get the 'left' property where the ticker stopped var stoppedtop = -parseint($parent.css('top')); // calculate the remaining distance the show must travel until the loop var remainingdistance = (stoppedtop) - $children.eq(0).height(); } // calculate the speed ratio to seamlessly finish the loop var finishingspeed = (remainingdistance * options.tickerspeed) / origshowheight; // call the show movetheshow(tickertop, remainingdistance, finishingspeed); // check if changetext argument is supplied if(typeof(changetext) == 'undefined'){ var changetext = true; } if(changetext && options.ticker){ $autocontrols.html($stopcontent).removeclass('start').addclass('stop'); autoplaying = true; } } } /** * initialize a new slideshow */ this.initshow = function(){ // reinitialize all variables // base = this; $parent = $(this); $origelement = $parent.clone(); $children = $parent.children(options.childselector); $outerwrapper = ''; $firstchild = $parent.children(options.childselector + ':first'); childrenwidth = $firstchild.width(); childrenmaxwidth = 0; childrenouterwidth = $firstchild.outerwidth(); childrenmaxheight = 0; wrapperwidth = getwrapperwidth(); wrapperheight = getwrapperheight(); isworking = false; $pager = ''; currentslide = 0; origleft = 0; origtop = 0; interval = ''; $autocontrols = ''; $stophtml = ''; $startcontent = ''; $stopcontent = ''; autoplaying = true; loaded = false; origshowwidth = 0; origshowheight = 0; tickerleft = 0; tickertop = 0; firstslide = 0; lastslide = $children.length - 1; // get the largest child's height and width $children.each(function(index) { if($(this).outerheight() > childrenmaxheight){ childrenmaxheight = $(this).outerheight(); } if($(this).outerwidth() > childrenmaxwidth){ childrenmaxwidth = $(this).outerwidth(); } }); // get random slide number if(options.randomstart){ var randomnumber = math.floor(math.random() * $children.length); currentslide = randomnumber; origleft = childrenouterwidth * (options.moveslideqty + randomnumber); origtop = childrenmaxheight * (options.moveslideqty + randomnumber); // start show at specific slide }else{ currentslide = options.startingslide; origleft = childrenouterwidth * (options.moveslideqty + options.startingslide); origtop = childrenmaxheight * (options.moveslideqty + options.startingslide); } // set initial css initcss(); // check to show pager if(options.pager && !options.ticker){ if(options.pagertype == 'full'){ showpager('full'); }else if(options.pagertype == 'short'){ showpager('short'); } } // check to show controls if(options.controls && !options.ticker && $children.length > 1){ setcontrolsvars(); } // check if auto if(options.auto || options.ticker){ // check if auto controls are displayed if(options.autocontrols){ setautocontrolsvars(); } // check if show should auto start if(options.autostart){ // check if autostart should delay autoplaying = false; // prevent playing during the deplay settimeout(function(){ base.startshow(true); }, options.autodelay); }else{ base.stopshow(true); } // check if show should pause on hover if(options.autohover && !options.ticker){ setautohover(); } } // make the starting slide active if(options.moveslideqty > 1){ makeslideactive(math.ceil(currentslide / options.moveslideqty)); }else{ makeslideactive(currentslide); } // check for finite show and if controls should be hidden checkendcontrols(); // show captions if(options.captions){ showcaptions(); } // perform the callback function options.onafterslide(currentslide, $children.length, $children.eq(currentslide)); } /** * destroy the current slideshow */ this.destroyshow = function(){ // stop the auto show clearinterval(interval); // remove any controls / pagers that have been appended $outerwrapper.children('.bx-next, .bx-prev, .bx-pager, .bx-auto').remove(); // unwrap all bx-wrappers $parent.unwrap().unwrap().removeattr('style'); // remove any styles that were appended $parent.children(options.childselector).removeattr('style').not('.bx-child').remove(); // remove any childrent that were appended $children.removeclass('bx-child'); } /** * reload the current slideshow */ this.reloadshow = function(){ base.destroyshow(); base.initshow(); } // private functions /** * creates all neccessary styling for the slideshow */ function initcss(){ // layout the children setchildrenlayout(options.startingslide); // css for horizontal mode if(options.mode == 'horizontal'){ // wrap the