/* 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: '', // Changes the text for the Previous button
nextText: '' // 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");
});
var navDisplay = '
\n';
for (var catIndex in navCategories) {
navList[navCategories[catIndex]] = navList[navCategories[catIndex]] + "
\n\n";
}
for (var navIndex in navList) {
navDisplay += navList[navIndex];
}
navDisplay += '';
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);
$(function(){
/*$(".flipster").flipster({
style: 'carousel',
enableNav: true
});*/
$(".flipster").flipster({
itemContainer: 'ul', // Container for the flippin' items.
itemSelector: 'li', // Selector for children of itemContainer to flip
style: 'carousel', // Switch between 'coverflow' or 'carousel' display styles
start: 0, // 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
enableNav: true, // If true, flipster will insert an unordered list of the slides
enableNavButtons: true, // If true, flipster will insert Previous / Next buttons
onItemSwitch: function(){}, // Callback function when items are switches
});
});