/* global window, document, jquery */ (function($) { $.fn.flipster = function(options) { var ismethodcall = typeof options === 'string' ? true : false; if (ismethodcall) { var method = options; var args = array.prototype.slice.call(arguments, 1); } else { var defaults = { itemcontainer: 'ul', // container for the flippin' items. itemselector: 'li', // selector for children of itemcontainer to flip style: 'coverflow', // switch between 'coverflow' or 'carousel' display styles start: 'center', // starting item. set to 0 to start at the first, 'center' to start in the middle or the index of the item you want to start with. enablekeyboard: true, // enable left/right arrow navigation enablemousewheel: true, // enable scrollwheel navigation (up = left, down = right) enabletouch: true, // enable swipe navigation for touch devices onitemswitch: $.noop, // callback function when items are switched disablerotation: false, enablenav: false, // if true, flipster will insert an unordered list of the slides navposition: 'before', // [before|after] changes the position of the navigation before or after the flipsterified items - case-insensitive enablenavbuttons: false, // if true, flipster will insert previous / next buttons prevtext: 'previous', // changes the text for the previous button nexttext: 'next' // changes the text for the next button }; var settings = $.extend({}, defaults, options); var win = $(window); } return this.each(function(){ var _flipster = $(this); var methods; if (ismethodcall) { methods = _flipster.data('methods'); return methods[method].apply(this, args); } var _flipitemsouter; var _flipitems; var _flipnav; var _flipnavitems; var _current = 0; var _starttouchx = 0; var _actionthrottle = 0; var _throttletimeout; var compatibility; // public methods methods = { jump: jump }; _flipster.data('methods', methods); function removethrottle() { _actionthrottle = 0; } function resize() { _flipitemsouter.height(calculatebiggestflipitemheight()); _flipster.css("height","auto"); if ( settings.style === 'carousel' ) { _flipitemsouter.width(_flipitems.width()); } } function calculatebiggestflipitemheight() { var biggestheight = 0; _flipitems.each(function() { if ($(this).height() > biggestheight) biggestheight = $(this).height(); }); return biggestheight; } function buildnav() { if ( settings.enablenav && _flipitems.length > 1 ) { var navcategories = [], navitems = [], navlist = []; _flipitems.each(function(){ var category = $(this).data("flip-category"), itemid = $(this).attr("id"), itemtitle = $(this).attr("title"); if ( typeof category !== 'undefined' ) { if ( $.inarray(category,navcategories) < 0 ) { navcategories.push(category); navlist[category] = '
  • '+category+'\n'; if(settings.navposition.tolowercase() != "after") { _flipnav = $(navdisplay).prependto(_flipster); } else { _flipnav = $(navdisplay).appendto(_flipster); } _flipnavitems = _flipnav.find("a").on("click",function(e){ var target; if ( $(this).hasclass("flip-nav-category-link") ) { target = _flipitems.filter("[data-flip-category='"+$(this).data("flip-category")+"']"); } else { target = $(this.hash); } if ( target.length ) { jump(target); e.preventdefault(); } }); } } function updatenav() { if ( settings.enablenav && _flipitems.length > 1 ) { var currentitem = $(_flipitems[_current]); _flipnav.find(".flip-nav-current").removeclass("flip-nav-current"); _flipnavitems.filter("[href='#"+currentitem.attr("id")+"']").addclass("flip-nav-current"); _flipnavitems.filter("[data-flip-category='"+currentitem.data("flip-category")+"']").parent().addclass("flip-nav-current"); } } function buildnavbuttons() { if ( settings.enablenavbuttons && _flipitems.length > 1 ) { _flipster.find(".flipto-prev, .flipto-next").remove(); _flipster.append(""+settings.prevtext+" "+settings.nexttext+""); _flipster.children('.flipto-prev').on("click", function(e) { jump("left"); e.preventdefault(); }); _flipster.children('.flipto-next').on("click", function(e) { jump("right"); e.preventdefault(); }); } } function center() { var currentitem = $(_flipitems[_current]).addclass("flip-current"); _flipitems.removeclass("flip-prev flip-next flip-current flip-past flip-future no-transition"); if ( settings.style === 'carousel' ) { _flipitems.addclass("flip-hidden"); var nextitem = $(_flipitems[_current+1]), futureitem = $(_flipitems[_current+2]), previtem = $(_flipitems[_current-1]), pastitem = $(_flipitems[_current-2]); if ( _current === 0 ) { previtem = _flipitems.last(); pastitem = previtem.prev(); } else if ( _current === 1 ) { pastitem = _flipitems.last(); } else if ( _current === _flipitems.length-2 ) { futureitem = _flipitems.first(); } else if ( _current === _flipitems.length-1 ) { nextitem = _flipitems.first(); futureitem = $(_flipitems[1]); } futureitem.removeclass("flip-hidden").addclass("flip-future"); pastitem.removeclass("flip-hidden").addclass("flip-past"); nextitem.removeclass("flip-hidden").addclass("flip-next"); previtem.removeclass("flip-hidden").addclass("flip-prev"); } else { var spacer = currentitem.outerwidth()/2; var totalleft = 0; var totalwidth = _flipitemsouter.width(); var currentwidth = currentitem.outerwidth(); var currentleft = (_flipitems.index(currentitem)*currentwidth)/2 +spacer/2; _flipitems.removeclass("flip-hidden"); for (var i = 0; i < _flipitems.length; i++) { var thisitem = $(_flipitems[i]); var thiswidth = thisitem.outerwidth(); if (i < _current) { thisitem.addclass("flip-past") .css({ "z-index" : i, "left" : (i*thiswidth/2)+"px" }); } else if ( i > _current ) { thisitem.addclass("flip-future") .css({ "z-index" : _flipitems.length-i, "left" : (i*thiswidth/2)+spacer+"px" }); } } currentitem.css({ "z-index" : _flipitems.length+1, "left" : currentleft +"px" }); totalleft = (currentleft + (currentwidth/2)) - (totalwidth/2); var newleftpos = -1*(totalleft)+"px"; /* untested compatibility */ if (compatibility) { var leftitems = $(".flip-past"); var rightitems = $(".flip-future"); $(".flip-current").css("zoom", "1.0"); for (i = 0; i < leftitems.length; i++) { $(leftitems[i]).css("zoom", (100-((leftitems.length-i)*5)+"%")); } for (i = 0; i < rightitems.length; i++) { $(rightitems[i]).css("zoom", (100-((i+1)*5)+"%")); } _flipitemsouter.animate({"left":newleftpos}, 333); } else { _flipitemsouter.css("left", newleftpos); } } currentitem .addclass("flip-current") .removeclass("flip-prev flip-next flip-past flip-future flip-hidden"); resize(); updatenav(); settings.onitemswitch.call(this); } function jump(to) { if ( _flipitems.length > 1 ) { if ( to === "left" ) { if ( _current > 0 ) { _current--; } else { _current = _flipitems.length-1; } } else if ( to === "right" ) { if ( _current < _flipitems.length-1 ) { _current++; } else { _current = 0; } } else if ( typeof to === 'number' ) { _current = to; } else { // if object is sent, get its index _current = _flipitems.index(to); } center(); } } function init() { // basic setup _flipster.addclass("flipster flipster-active flipster-"+settings.style).css("visibility","hidden"); if (settings.disablerotation) _flipster.addclass('no-rotate'); _flipitemsouter = _flipster.find(settings.itemcontainer).addclass("flip-items"); _flipitems = _flipitemsouter.find(settings.itemselector).addclass("flip-item flip-hidden").wrapinner("
    "); //browsers that don't support css3 transforms get compatibility: var isiemax8 = ('\v' === 'v'); //ie <= 8 var checkie = document.createelement("b"); checkie.innerhtml = ""; //ie 9 var isie9 = checkie.getelementsbytagname("i").length === 1; if (isiemax8 || isie9) { compatibility = true; _flipitemsouter.addclass("compatibility"); } // insert navigation if enabled. buildnav(); buildnavbuttons(); // set the starting item if (settings.start && _flipitems.length > 1) { // find the middle item if start = center if ( settings.start === 'center' ) { if (!_flipitems.length % 2) { _current = _flipitems.length/2 + 1; } else { _current = math.floor(_flipitems.length/2); } } else { _current = settings.start; } } // initialize containers resize(); // necessary to start flipster invisible and then fadein so height/width can be set accurately after page load _flipster.hide().css("visibility","visible").fadein(400,function(){ center(); }); // attach event bindings. win.on("resize.flipster", function() { resize(); center(); }); // navigate directly to an item by clicking _flipitems.on("click", function(e) { if ( !$(this).hasclass("flip-current") ) { e.preventdefault(); } jump(_flipitems.index(this)); }); // keyboard navigation if (settings.enablekeyboard && _flipitems.length > 1) { win.on("keydown.flipster", function(e) { _actionthrottle++; if (_actionthrottle % 7 !== 0 && _actionthrottle !== 1) return; //if holding the key down, ignore most events var code = e.which; if (code === 37 ) { e.preventdefault(); jump('left'); } else if (code === 39 ) { e.preventdefault(); jump('right'); } }); win.on("keyup.flipster", function(e){ _actionthrottle = 0; //reset action throttle on key lift to avoid throttling new interactions }); } // mousewheel navigation if (settings.enablemousewheel && _flipitems.length > 1) { // todo: fix scrollwheel on firefox _flipster.on("mousewheel.flipster", function(e){ _throttletimeout = window.settimeout(removethrottle, 500); //throttling should expire if scrolling pauses for a moment. _actionthrottle++; if (_actionthrottle % 4 !==0 && _actionthrottle !== 1) return; //throttling like with held-down keys window.cleartimeout(_throttletimeout); if ( e.originalevent.wheeldelta /120 > 0 ) { jump("left"); } else { jump("right"); } e.preventdefault(); }); } // touch navigation if ( settings.enabletouch && _flipitems.length > 1 ) { _flipster.on("touchstart.flipster", function(e) { _starttouchx = e.originalevent.targettouches[0].screenx; }); _flipster.on("touchmove.flipster", function(e) { e.preventdefault(); var nowx = e.originalevent.targettouches[0].screenx; var touchdiff = nowx-_starttouchx; if (touchdiff > _flipitems[0].clientwidth/1.75){ jump("left"); _starttouchx = nowx; }else if (touchdiff < -1*(_flipitems[0].clientwidth/1.75)){ jump("right"); _starttouchx = nowx; } }); _flipster.on("touchend.flipster", function(e) { _starttouchx = 0; }); } } // initialize if flipster is not already active. if ( !_flipster.hasclass("flipster-active") ) { init(); } }); }; })(jquery);