/* * jquery flexslider v1.8 * http://flex.madebymufffin.com * * copyright 2011, tyler smith * free to use under the mit license. * http://www.opensource.org/licenses/mit-license.php * * contrib: darin richardson */ ;(function ($) { //flexslider: object instance $.flexslider = function(el, options) { var slider = el; slider.init = function() { slider.vars = $.extend({}, $.flexslider.defaults, options); slider.data('flexslider', true); slider.container = $('.slides', slider); slider.slides = $('.slides > li', slider); slider.count = slider.slides.length; slider.animating = false; slider.currentslide = slider.vars.slidetostart; slider.animatingto = slider.currentslide; slider.atend = (slider.currentslide == 0) ? true : false; slider.eventtype = ('ontouchstart' in document.documentelement) ? 'touchstart' : 'click'; slider.clonecount = 0; slider.cloneoffset = 0; slider.manualpause = false; slider.vertical = (slider.vars.slidedirection == "vertical"); slider.prop = (slider.vertical) ? "top" : "marginleft"; slider.args = {}; //test for webbkit css3 animations slider.transitions = "webkittransition" in document.body.style; if (slider.transitions) slider.prop = "-webkit-transform"; //test for controlscontainer if (slider.vars.controlscontainer != "") { slider.controlscontainer = $(slider.vars.controlscontainer).eq($('.slides').index(slider.container)); slider.containerexists = slider.controlscontainer.length > 0; } //test for manualcontrols if (slider.vars.manualcontrols != "") { slider.manualcontrols = $(slider.vars.manualcontrols, ((slider.containerexists) ? slider.controlscontainer : slider)); slider.manualexists = slider.manualcontrols.length > 0; } /////////////////////////////////////////////////////////////////// // flexslider: randomize slides if (slider.vars.randomize) { slider.slides.sort(function() { return (math.round(math.random())-0.5); }); slider.container.empty().append(slider.slides); } /////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////// // flexslider: slider animation initialize if (slider.vars.animation.tolowercase() == "slide") { if (slider.transitions) { slider.settransition(0); } slider.css({"overflow": "hidden"}); if (slider.vars.animationloop) { slider.clonecount = 2; slider.cloneoffset = 1; slider.container.append(slider.slides.filter(':first').clone().addclass('clone')).prepend(slider.slides.filter(':last').clone().addclass('clone')); } //create newslides to capture possible clones slider.newslides = $('.slides > li', slider); var slideroffset = (-1 * (slider.currentslide + slider.cloneoffset)); if (slider.vertical) { slider.newslides.css({"display": "block", "width": "100%", "float": "left"}); slider.container.height((slider.count + slider.clonecount) * 200 + "%").css("position", "absolute").width("100%"); //timeout function to give browser enough time to get proper height initially settimeout(function() { slider.css({"position": "relative"}).height(slider.slides.filter(':first').height()); slider.args[slider.prop] = (slider.transitions) ? "translate3d(0," + slideroffset * slider.height() + "px,0)" : slideroffset * slider.height() + "px"; slider.container.css(slider.args); }, 100); } else { slider.args[slider.prop] = (slider.transitions) ? "translate3d(" + slideroffset * slider.width() + "px,0,0)" : slideroffset * slider.width() + "px"; slider.container.width((slider.count + slider.clonecount) * 200 + "%").css(slider.args); //timeout function to give browser enough time to get proper width initially settimeout(function() { slider.newslides.width(slider.width()).css({"float": "left", "display": "block"}); }, 100); } } else { //default to fade //not supporting fade css3 transitions right now slider.transitions = false; slider.slides.css({"width": "100%", "float": "left", "marginright": "-100%"}).eq(slider.currentslide).fadein(slider.vars.animationduration); } /////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////// // flexslider: control nav if (slider.vars.controlnav) { if (slider.manualexists) { slider.controlnav = slider.manualcontrols; } else { var controlnavscaffold = $('
    '); var j = 1; for (var i = 0; i < slider.count; i++) { controlnavscaffold.append('
  1. ' + j + '
  2. '); j++; } if (slider.containerexists) { $(slider.controlscontainer).append(controlnavscaffold); slider.controlnav = $('.flex-control-nav li a', slider.controlscontainer); } else { slider.append(controlnavscaffold); slider.controlnav = $('.flex-control-nav li a', slider); } } slider.controlnav.eq(slider.currentslide).addclass('active'); slider.controlnav.bind(slider.eventtype, function(event) { event.preventdefault(); if (!$(this).hasclass('active')) { (slider.controlnav.index($(this)) > slider.currentslide) ? slider.direction = "next" : slider.direction = "prev"; slider.flexanimate(slider.controlnav.index($(this)), slider.vars.pauseonaction); } }); } /////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////// //flexslider: direction nav if (slider.vars.directionnav) { var directionnavscaffold = $(''); if (slider.containerexists) { $(slider.controlscontainer).append(directionnavscaffold); slider.directionnav = $('.flex-direction-nav li a', slider.controlscontainer); } else { slider.append(directionnavscaffold); slider.directionnav = $('.flex-direction-nav li a', slider); } //set initial disable styles if necessary if (!slider.vars.animationloop) { if (slider.currentslide == 0) { slider.directionnav.filter('.prev').addclass('disabled'); } else if (slider.currentslide == slider.count - 1) { slider.directionnav.filter('.next').addclass('disabled'); } } slider.directionnav.bind(slider.eventtype, function(event) { event.preventdefault(); var target = ($(this).hasclass('next')) ? slider.gettarget('next') : slider.gettarget('prev'); if (slider.canadvance(target)) { slider.flexanimate(target, slider.vars.pauseonaction); } }); } ////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////// //flexslider: keyboard nav if (slider.vars.keyboardnav && $('ul.slides').length == 1) { function keyboardmove(event) { if (slider.animating) { return; } else if (event.keycode != 39 && event.keycode != 37){ return; } else { if (event.keycode == 39) { var target = slider.gettarget('next'); } else if (event.keycode == 37){ var target = slider.gettarget('prev'); } if (slider.canadvance(target)) { slider.flexanimate(target, slider.vars.pauseonaction); } } } $(document).bind('keyup', keyboardmove); } ////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////// // flexslider: mousewheel interaction if (slider.vars.mousewheel) { slider.mousewheelevent = (/firefox/i.test(navigator.useragent)) ? "dommousescroll" : "mousewheel"; slider.bind(slider.mousewheelevent, function(e) { e.preventdefault(); e = e ? e : window.event; var wheeldata = e.detail ? e.detail * -1 : e.wheeldelta / 40, target = (wheeldata < 0) ? slider.gettarget('next') : slider.gettarget('prev'); if (slider.canadvance(target)) { slider.flexanimate(target, slider.vars.pauseonaction); } }); } /////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////// //flexslider: slideshow setup if (slider.vars.slideshow) { //pauseonhover if (slider.vars.pauseonhover && slider.vars.slideshow) { slider.hover(function() { slider.pause(); }, function() { if (!slider.manualpause) { slider.resume(); } }); } //initialize animation slider.animatedslides = setinterval(slider.animateslides, slider.vars.slideshowspeed); } ////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////// //flexslider: pause/play if (slider.vars.pauseplay) { var pauseplayscaffold = $('
    '); if (slider.containerexists) { slider.controlscontainer.append(pauseplayscaffold); slider.pauseplay = $('.flex-pauseplay span', slider.controlscontainer); } else { slider.append(pauseplayscaffold); slider.pauseplay = $('.flex-pauseplay span', slider); } var pauseplaystate = (slider.vars.slideshow) ? 'pause' : 'play'; slider.pauseplay.addclass(pauseplaystate).text((pauseplaystate == 'pause') ? slider.vars.pausetext : slider.vars.playtext); slider.pauseplay.bind(slider.eventtype, function(event) { event.preventdefault(); if ($(this).hasclass('pause')) { slider.pause(); slider.manualpause = true; } else { slider.resume(); slider.manualpause = false; } }); } ////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////// //flexslider:touch swip gestures //some brilliant concepts adapted from the following sources //source: touchswipe - http://www.netcu.de/jquery-touchwipe-iphone-ipad-library //source: swipejs - http://swipejs.com if ('ontouchstart' in document.documentelement) { //for brevity, variables are named for x-axis scrolling //the variables are then swapped if vertical sliding is applied //this reduces redundant code...i think :) //if debugging, recognize variables are named for horizontal scrolling var startx, starty, offset, cwidth, dx, startt, scrolling = false; slider.each(function() { if ('ontouchstart' in document.documentelement) { this.addeventlistener('touchstart', ontouchstart, false); } }); function ontouchstart(e) { if (slider.animating) { e.preventdefault(); } else if (e.touches.length == 1) { slider.pause(); cwidth = (slider.vertical) ? slider.height() : slider.width(); startt = number(new date()); offset = (slider.vertical) ? (slider.currentslide + slider.cloneoffset) * slider.height() : (slider.currentslide + slider.cloneoffset) * slider.width(); startx = (slider.vertical) ? e.touches[0].pagey : e.touches[0].pagex; starty = (slider.vertical) ? e.touches[0].pagex : e.touches[0].pagey; slider.settransition(0); this.addeventlistener('touchmove', ontouchmove, false); this.addeventlistener('touchend', ontouchend, false); } } function ontouchmove(e) { dx = (slider.vertical) ? startx - e.touches[0].pagey : startx - e.touches[0].pagex; scrolling = (slider.vertical) ? (math.abs(dx) < math.abs(e.touches[0].pagex - starty)) : (math.abs(dx) < math.abs(e.touches[0].pagey - starty)); if (!scrolling) { e.preventdefault(); if (slider.vars.animation == "slide" && slider.transitions) { if (!slider.vars.animationloop) { dx = dx/((slider.currentslide == 0 && dx < 0 || slider.currentslide == slider.count - 1 && dx > 0) ? (math.abs(dx)/cwidth+2) : 1); } slider.args[slider.prop] = (slider.vertical) ? "translate3d(0," + (-offset - dx) + "px,0)": "translate3d(" + (-offset - dx) + "px,0,0)"; slider.container.css(slider.args); } } } function ontouchend(e) { slider.animating = false; if (slider.animatingto == slider.currentslide && !scrolling && !(dx == null)) { var target = (dx > 0) ? slider.gettarget('next') : slider.gettarget('prev'); if (slider.canadvance(target) && number(new date()) - startt < 550 && math.abs(dx) > 20 || math.abs(dx) > cwidth/2) { slider.flexanimate(target, slider.vars.pauseonaction); } else { slider.flexanimate(slider.currentslide, slider.vars.pauseonaction); } } //finish the touch by undoing the touch session this.removeeventlistener('touchmove', ontouchmove, false); this.removeeventlistener('touchend', ontouchend, false); startx = null; starty = null; dx = null; offset = null; } } ////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////// //flexslider: resize functions (if necessary) if (slider.vars.animation.tolowercase() == "slide") { $(window).resize(function(){ if (!slider.animating) { if (slider.vertical) { slider.height(slider.slides.filter(':first').height()); slider.args[slider.prop] = (-1 * (slider.currentslide + slider.cloneoffset))* slider.slides.filter(':first').height() + "px"; if (slider.transitions) { slider.settransition(0); slider.args[slider.prop] = (slider.vertical) ? "translate3d(0," + slider.args[slider.prop] + ",0)" : "translate3d(" + slider.args[slider.prop] + ",0,0)"; } slider.container.css(slider.args); } else { slider.newslides.width(slider.width()); slider.args[slider.prop] = (-1 * (slider.currentslide + slider.cloneoffset))* slider.width() + "px"; if (slider.transitions) { slider.settransition(0); slider.args[slider.prop] = (slider.vertical) ? "translate3d(0," + slider.args[slider.prop] + ",0)" : "translate3d(" + slider.args[slider.prop] + ",0,0)"; } slider.container.css(slider.args); } } }); } ////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////// //flexslider: destroy the slider entity //destory is not included in the minified version right now, but this is a working function for anyone who wants to include it. //simply bind the actions you need from this function into a function in the start() callback to the event of your chosing /* slider.destroy = function() { slider.pause(); if (slider.controlnav && slider.vars.manualcontrols == "") slider.controlnav.closest('.flex-control-nav').remove(); if (slider.directionnav) slider.directionnav.closest('.flex-direction-nav').remove(); if (slider.vars.pauseplay) slider.pauseplay.closest('.flex-pauseplay').remove(); if (slider.vars.keyboardnav && $('ul.slides').length == 1) $(document).unbind('keyup', keyboardmove); if (slider.vars.mousewheel) slider.unbind(slider.mousewheelevent); if (slider.transitions) slider.each(function(){this.removeeventlistener('touchstart', ontouchstart, false);}); if (slider.vars.animation == "slide" && slider.vars.animationloop) slider.newslides.filter('.clone').remove(); if (slider.vertical) slider.height("auto"); slider.slides.hide(); slider.removedata('flexslider'); } */ ////////////////////////////////////////////////////////////////// //flexslider: start() callback slider.vars.start(slider); } //flexslider: animation actions slider.flexanimate = function(target, pause) { if (!slider.animating) { //animating flag slider.animating = true; //flexslider: before() animation callback slider.animatingto = target; slider.vars.before(slider); //optional paramter to pause slider when making an anmiation call if (pause) { slider.pause(); } //update controlnav if (slider.vars.controlnav) { slider.controlnav.removeclass('active').eq(target).addclass('active'); } //is the slider at either end slider.atend = (target == 0 || target == slider.count - 1) ? true : false; if (!slider.vars.animationloop && slider.vars.directionnav) { if (target == 0) { slider.directionnav.removeclass('disabled').filter('.prev').addclass('disabled'); } else if (target == slider.count - 1) { slider.directionnav.removeclass('disabled').filter('.next').addclass('disabled'); } else { slider.directionnav.removeclass('disabled'); } } if (!slider.vars.animationloop && target == slider.count - 1) { slider.pause(); //flexslider: end() of cycle callback slider.vars.end(slider); } if (slider.vars.animation.tolowercase() == "slide") { var dimension = (slider.vertical) ? slider.slides.filter(':first').height() : slider.slides.filter(':first').width(); if (slider.currentslide == 0 && target == slider.count - 1 && slider.vars.animationloop && slider.direction != "next") { slider.slidestring = "0px"; } else if (slider.currentslide == slider.count - 1 && target == 0 && slider.vars.animationloop && slider.direction != "prev") { slider.slidestring = (-1 * (slider.count + 1)) * dimension + "px"; } else { slider.slidestring = (-1 * (target + slider.cloneoffset)) * dimension + "px"; } slider.args[slider.prop] = slider.slidestring; if (slider.transitions) { slider.settransition(slider.vars.animationduration); slider.args[slider.prop] = (slider.vertical) ? "translate3d(0," + slider.slidestring + ",0)" : "translate3d(" + slider.slidestring + ",0,0)"; slider.container.css(slider.args).one("webkittransitionend transitionend", function(){ slider.wrapup(dimension); }); } else { slider.container.animate(slider.args, slider.vars.animationduration, function(){ slider.wrapup(dimension); }); } } else { //default to fade slider.slides.eq(slider.currentslide).fadeout(slider.vars.animationduration); slider.slides.eq(target).fadein(slider.vars.animationduration, function() { slider.wrapup(); }); } } } //flexslider: function to minify redundant animation actions slider.wrapup = function(dimension) { if (slider.vars.animation == "slide") { //jump the slider if necessary if (slider.currentslide == 0 && slider.animatingto == slider.count - 1 && slider.vars.animationloop) { slider.args[slider.prop] = (-1 * slider.count) * dimension + "px"; if (slider.transitions) { slider.settransition(0); slider.args[slider.prop] = (slider.vertical) ? "translate3d(0," + slider.args[slider.prop] + ",0)" : "translate3d(" + slider.args[slider.prop] + ",0,0)"; } slider.container.css(slider.args); } else if (slider.currentslide == slider.count - 1 && slider.animatingto == 0 && slider.vars.animationloop) { slider.args[slider.prop] = -1 * dimension + "px"; if (slider.transitions) { slider.settransition(0); slider.args[slider.prop] = (slider.vertical) ? "translate3d(0," + slider.args[slider.prop] + ",0)" : "translate3d(" + slider.args[slider.prop] + ",0,0)"; } slider.container.css(slider.args); } } slider.animating = false; slider.currentslide = slider.animatingto; //flexslider: after() animation callback slider.vars.after(slider); } //flexslider: automatic slideshow slider.animateslides = function() { if (!slider.animating) { slider.flexanimate(slider.gettarget("next")); } } //flexslider: automatic slideshow pause slider.pause = function() { clearinterval(slider.animatedslides); if (slider.vars.pauseplay) { slider.pauseplay.removeclass('pause').addclass('play').text(slider.vars.playtext); } } //flexslider: automatic slideshow start/resume slider.resume = function() { slider.animatedslides = setinterval(slider.animateslides, slider.vars.slideshowspeed); if (slider.vars.pauseplay) { slider.pauseplay.removeclass('play').addclass('pause').text(slider.vars.pausetext); } } //flexslider: helper function for non-looping sliders slider.canadvance = function(target) { if (!slider.vars.animationloop && slider.atend) { if (slider.currentslide == 0 && target == slider.count - 1 && slider.direction != "next") { return false; } else if (slider.currentslide == slider.count - 1 && target == 0 && slider.direction == "next") { return false; } else { return true; } } else { return true; } } //flexslider: helper function to determine animation target slider.gettarget = function(dir) { slider.direction = dir; if (dir == "next") { return (slider.currentslide == slider.count - 1) ? 0 : slider.currentslide + 1; } else { return (slider.currentslide == 0) ? slider.count - 1 : slider.currentslide - 1; } } //flexslider: helper function to set css3 transitions slider.settransition = function(dur) { slider.container.css({'-webkit-transition-duration': (dur/1000) + "s"}); } //flexslider: initialize slider.init(); } //flexslider: default settings $.flexslider.defaults = { animation: "fade", //string: select your animation type, "fade" or "slide" slidedirection: "horizontal", //string: select the sliding direction, "horizontal" or "vertical" slideshow: true, //boolean: animate slider automatically slideshowspeed: 12000, //integer: set the speed of the slideshow cycling, in milliseconds animationduration: 1500, //integer: set the speed of animations, in milliseconds directionnav: true, //boolean: create navigation for previous/next navigation? (true/false) controlnav: true, //boolean: create navigation for paging control of each clide? note: leave true for manualcontrols usage keyboardnav: true, //boolean: allow slider navigating via keyboard left/right keys mousewheel: false, //boolean: allow slider navigating via mousewheel prevtext: "previous", //string: set the text for the "previous" directionnav item nexttext: "next", //string: set the text for the "next" directionnav item pauseplay: false, //boolean: create pause/play dynamic element pausetext: 'pause', //string: set the text for the "pause" pauseplay item playtext: 'play', //string: set the text for the "play" pauseplay item randomize: false, //boolean: randomize slide order slidetostart: 0, //integer: the slide that the slider should start on. array notation (0 = first slide) animationloop: true, //boolean: should the animation loop? if false, directionnav will received "disable" classes at either end pauseonaction: true, //boolean: pause the slideshow when interacting with control elements, highly recommended. pauseonhover: false, //boolean: pause the slideshow when hovering over slider, then resume when no longer hovering controlscontainer: "", //selector: declare which container the navigation elements should be appended too. default container is the flexslider element. example use would be ".flexslider-container", "#container", etc. if the given element is not found, the default action will be taken. manualcontrols: "", //selector: declare custom control navigation. example would be ".flex-control-nav li" or "#tabs-nav li img", etc. the number of elements in your controlnav should match the number of slides/tabs. start: function(){}, //callback: function(slider) - fires when the slider loads the first slide before: function(){}, //callback: function(slider) - fires asynchronously with each slider animation after: function(){}, //callback: function(slider) - fires after each slider animation completes end: function(){} //callback: function(slider) - fires when the slider reaches the last slide (asynchronous) } //flexslider: plugin function $.fn.flexslider = function(options) { return this.each(function() { if ($(this).find('.slides li').length == 1) { $(this).find('.slides li').fadein(400); } else if ($(this).data('flexslider') != true) { new $.flexslider($(this), options); } }); } })(jquery);