Template:SMTexas/JSbook
From 2014hs.igem.org
/*
* jQuery Booklet Plugin * Copyright (c) 2010 - 2014 William Grauvogel (http://builtbywill.com/) * * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php) * * Version : 1.4.4 * * Originally based on the work of: * 1) Charles Mangin (http://clickheredammit.com/pageflip/) */
- (function ($) {
$.fn.booklet = function (options, param1, param2) {
var obj, method, params, output, result, config, index;
// option type string - api call if (typeof options === 'string') { result = []; $(this).each(function () { obj = $(this).data('booklet'); if (obj) { method = options; // add optional parameters params = []; if (typeof param1 !== 'undefined') { params.push(param1); } if (typeof param2 !== 'undefined') { params.push(param2); } if (obj[method]) { output = obj[method].apply(obj, params); if (typeof output !== 'undefined' || output) { result.push(obj[method].apply(obj, params)); } } else { $.error('Method "' + method + '" does not exist on jQuery.booklet.'); } } else { $.error('jQuery.booklet has not been initialized. Method "' + options + '" cannot be called.'); } }); if (result.length == 1) { return result[0]; } else if (result.length > 0) { return result; } else { return $(this); } } // option type number - api call else if (typeof options === 'number') { return $(this).each(function () { obj = $(this).data('booklet'); if (obj) { index = options; obj.gotopage(index); } else { $.error('jQuery.booklet has not been initialized.'); } }); } // else build new booklet else if (typeof method === 'object' || !method) { return $(this).each(function () { config = $.extend({}, $.fn.booklet.defaults, options); obj = $(this).data('booklet');
// destroy old booklet before creating new one if (obj) { obj.destroy(); }
// instantiate the booklet obj = new Booklet($(this), config); obj.init();
return this; // preserve chaining on main function }); } };
function Booklet(inTarget, inOptions) { var target = inTarget, options = inOptions, isInit = false, isBusy = false, isPlaying = false, isHoveringRight = false, isHoveringLeft = false, isDisabled = false, templates = {empty: '', //book page with no content blank: '', //transparent item used with closed books sF: '', sB: ''
}, directions = { leftToRight: 'LTR', rightToLeft: 'RTL' }, css = {}, anim = {}, hoverShadowWidth, hoverFullWidth, hoverCurlWidth, pages = [],
currentHash = , hashRoot = '/page/', hash, i, j, h, a, diff, originalPageTotal, startingPageNumber, //page content vars pN, p0, p1, p2, p3, p4, pNwrap, p0wrap, p1wrap, p2wrap, p3wrap, p4wrap, wraps, sF, sB, //control vars p3drag, p0drag, ctrls, overlaysB, overlayN, overlayP, tabs, tabN, tabP, arrows, arrowN, arrowP, customN, customP, ctrlsN, ctrlsP, menu, pause, play, pageSelector, pageSelectorList, listItemNumbers, listItemTitle, pageListItem, pageSelectorHeight, chapter, chapterSelector, chapterSelectorList, chapterListItem, chapterSelectorHeight, wPercent, wOrig, hPercent, hOrig, pWidth, pWidthN, pWidthH, pHeight, speedH,
events = { create: 'bookletcreate', // called when booklet has been created start: 'bookletstart', // called when booklet starts to change pages change: 'bookletchange', // called when booklet has finished changing pages add: 'bookletadd', // called when booklet has added a page remove: 'bookletremove' // called when booklet has removed a page }, callback,
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // CLASSES /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Page = function (contentNode, index, options) { var chapter = , title = , pageNode;
// save chapter title if (contentNode.attr('rel')) { chapter = contentNode.attr('rel'); } // save page title if (contentNode.attr('title')) { title = contentNode.attr('title'); }
//give content the correct wrapper and page wrapper if (contentNode.hasClass('b-page-empty')) {contentNode.wrap('
} else if (options.closed && options.covers && (index == 1 || index == options.pageTotal - 2)) {contentNode.wrap('
} else if (index % 2 != 0) {contentNode.wrap('
} else {contentNode.wrap('
}
pageNode = contentNode.parents('.b-page').addClass('b-page-' + index);
// add page numbers if ( options.pageNumbers && !contentNode.hasClass('b-page-empty') && //(options.layoutSingle && !contentNode.hasClass('b-page-blank')) && (!options.closed || (options.closed && !options.covers) || (options.closed && options.covers && index != 1 && index != options.pageTotal - 2)) ) { if (options.direction == directions.leftToRight) { startingPageNumber++; }contentNode.parent().append('
if (options.direction == directions.rightToLeft) { startingPageNumber--; } }
return { index: index, contentNode: contentNode[0], pageNode: pageNode[0], chapter: chapter, title: title } },
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // INITIAL FUNCTIONS /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
init = function () { // remove load wrapper for compatibility with version 1.2.0 target.find('.b-load').children().unwrap();
// setup target DOM object target.addClass('booklet');
// store data for api calls target.data('booklet', this);
// save original number of pages originalPageTotal = target.children().length; options.currentIndex = 0;
// generate page markup initPages(); // initialize options updateOptions(); // update after initialized updatePages();
updateControlVisibility(); updateMenu();
isInit = true; isDisabled = false;
callback = { options: $.extend({}, options), index: options.currentIndex, pages: [pages[options.currentIndex].contentNode, pages[options.currentIndex + 1].contentNode] }; if (options.create) { target.off(events.create + '.booklet').on(events.create + '.booklet', options.create); } target.trigger(events.create, callback); }, enable = function () { isDisabled = false; }, disable = function () { isDisabled = true; }, destroy = function () { // destroy all booklet items destroyControls(); destroyPages();
// clear class from target DOM object target.removeClass('booklet');
// clear out booklet from data object target.removeData('booklet');
isInit = false; },
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // PAGE FUNCTIONS /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
initPages = function () {
pages = [];
// fix for odd number of pages if ((target.children().length % 2) != 0) { // if book is closed and using covers, add page before back cover, else after last page if (options.closed && options.covers) { target.children().last().before(templates.blank); } else { target.children().last().after(templates.blank); } }
// if closed book, add empty pages to start and end if (options.closed) { $(templates.empty).attr({ title: options.closedFrontTitle || , rel: options.closedFrontChapter || }).prependTo(target); target.children().last().attr({ title: options.closedBackTitle || , rel: options.closedBackChapter || }); target.append(templates.empty); }
// set total page count options.pageTotal = target.children().length;
startingPageNumber = 0;
if (options.direction == directions.rightToLeft) { startingPageNumber = options.pageTotal; if (options.closed) { startingPageNumber -= 2; } if (options.covers) { startingPageNumber -= 2; } $(target.children().get().reverse()).each(function () { $(this).appendTo(target); }); }
if (!isInit) { // set currentIndex if (options.direction == directions.leftToRight) { options.currentIndex = 0; } else if (options.direction == directions.rightToLeft) { options.currentIndex = options.pageTotal - 2; }
if (!isNaN(options.startingPage) && options.startingPage <= options.pageTotal && options.startingPage > 0) { if ((options.startingPage % 2) != 0) { options.startingPage--; } options.currentIndex = options.startingPage; } }
/* if(options.layoutSingle) { target.children().each(function () { if(options.direction == directions.leftToRight){ $(this).before(templates.blank); }else{ $(this).after(templates.blank); } }); } */
// load pages target.children().each(function (i) { var newPage = new Page($(this), i, options); pages.push(newPage); }); }, updatePages = function () { updatePageStructure(); updatePageCSS(); updateManualControls(); }, updatePageStructure = function () { // reset all content target.find('.b-page').removeClass('b-pN b-p0 b-p1 b-p2 b-p3 b-p4').hide();
// add page classes if (options.currentIndex - 2 >= 0) { target.find('.b-page-' + (options.currentIndex - 2)).addClass('b-pN').show(); target.find('.b-page-' + (options.currentIndex - 1)).addClass('b-p0').show(); } target.find('.b-page-' + (options.currentIndex)).addClass('b-p1').show(); target.find('.b-page-' + (options.currentIndex + 1)).addClass('b-p2').show(); if (options.currentIndex + 3 <= options.pageTotal) { target.find('.b-page-' + (options.currentIndex + 2)).addClass('b-p3').show(); target.find('.b-page-' + (options.currentIndex + 3)).addClass('b-p4').show(); }
// save structure elems to vars pN = target.find('.b-pN'); p0 = target.find('.b-p0'); p1 = target.find('.b-p1'); p2 = target.find('.b-p2'); p3 = target.find('.b-p3'); p4 = target.find('.b-p4'); pNwrap = target.find('.b-pN .b-wrap'); p0wrap = target.find('.b-p0 .b-wrap'); p1wrap = target.find('.b-p1 .b-wrap'); p2wrap = target.find('.b-p2 .b-wrap'); p3wrap = target.find('.b-p3 .b-wrap'); p4wrap = target.find('.b-p4 .b-wrap'); wraps = target.find('.b-wrap');
if (options.shadows) { target.find('.b-shadow-f, .b-shadow-b').remove(); sF = $(templates.sF).css(css.sF).appendTo(p3); sB = $(templates.sB).appendTo(p0).css(css.sB); } }, updatePageCSS = function () { // update css target.find('.b-shadow-f, .b-shadow-b, .b-p0, .b-p3').css({ 'filter': , 'zoom': });
target.find('.b-page').removeAttr('style'); wraps.removeAttr('style');
wraps.css(css.wrap); p0wrap.css(css.p0wrap); p1.css(css.p1); p2.css(css.p2); if (options.closed && options.autoCenter && options.currentIndex >= options.pageTotal - 2) { p2.hide(); } pN.css(css.pN); p0.css(css.p0); p3.stop().css(css.p3); p4.css(css.p4);
if (options.closed && options.autoCenter && options.currentIndex == 0) { pN.css({ 'left': 0 }); p1.css({ 'left': pWidthN }); p2.css({ 'left': 0 }); p3.css({ 'left': pWidth }); p4.css({ 'left': 0 }); }
if (options.closed && options.autoCenter && (options.currentIndex == 0 || options.currentIndex >= options.pageTotal - 2)) { if (options.overlays) { overlaysB.width('100%'); } target.width(pWidth); } else { if (options.overlays) { overlaysB.width('50%'); } target.width(options.width); }
// ie fix target.find('.b-page').css({ 'filter': , 'zoom': }); }, destroyPages = function () { // remove booklet markup target.find(".b-wrap").unwrap(); target.find(".b-wrap").children().unwrap(); target.find(".b-counter, .b-page-blank, .b-page-empty, .b-shadow-f, .b-shadow-b").remove();
// revert page order to original if (options.direction == directions.rightToLeft) { $(target.children().get().reverse()).each(function () { $(this).appendTo(target); }); } },
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // OPTION / CONTROL FUNCTIONS /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
updateOptions = function (newOptions) {
var didUpdate = false;
// update options if newOptions have been passed in if (newOptions != null && typeof newOptions != "undefined") {
// remove page structure, revert to original order destroyPages(); destroyControls();
options = $.extend({}, options, newOptions); didUpdate = true;
initPages(); }
// set width + height if (!options.width) { options.width = target.width(); } else if (typeof options.width == 'string' && options.width.indexOf("px") != -1) { options.width = options.width.replace('px', ); } else if (typeof options.width == 'string' && options.width.indexOf("%") != -1) { wPercent = true; wOrig = options.width; options.width = (options.width.replace('%', ) / 100) * parseFloat(target.parent().css('width')); } if (!options.height) { options.height = target.height(); } else if (typeof options.height == 'string' && options.height.indexOf("px") != -1) { options.height = options.height.replace('px', ); } else if (typeof options.height == 'string' && options.height.indexOf("%") != -1) { hPercent = true; hOrig = options.height; options.height = (options.height.replace('%', ) / 100) * parseFloat(target.parent().css('height')); } target.width(options.width); target.height(options.height);
// save page sizes and other vars pWidth = options.width / 2; pWidthN = '-' + (pWidth) + 'px'; pWidthH = pWidth / 2; pHeight = options.height; speedH = options.speed / 2;
// set position if (options.closed && options.autoCenter) { if (options.currentIndex == 0) { target.width(pWidth); } else if (options.currentIndex >= options.pageTotal - 2) { target.width(pWidth); } }
// save shadow widths for anim if (options.shadows) { options.shadowTopFwdWidth = '-' + options.shadowTopFwdWidth + 'px'; options.shadowTopBackWidth = '-' + options.shadowTopBackWidth + 'px'; }
// set total page count options.pageTotal = target.children('.b-page').length;
// set booklet opts.name if (options.name) { document.title = options.name; } else { options.name = document.title; }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// update all CSS, as sizes may have changed updateCSSandAnimations(); if (isInit) { updatePages(); }
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // MENU /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// setup menu if (options.menu && $(options.menu).length > 0) { menu = $(options.menu);
if (!menu.hasClass('b-menu')) { menu.addClass('b-menu'); }
// setup page selector if (options.pageSelector && menu.find('.b-selector-page').length == 0) { //add selectorpageSelector = $('
// loop through all pages for (i = 0; i < options.pageTotal; i += 2) { j = i; // numbers for normal view listItemNumbers = (j + 1) + '-' + (j + 2); if (options.closed) { // numbers for closed book j--; if (i == 0) { listItemNumbers = '1' } else if (i == options.pageTotal - 2) { listItemNumbers = options.pageTotal - 2 } else { listItemNumbers = (j + 1) + '-' + (j + 2); } // numbers for closed book with covers if (options.covers) { j--; if (i == 0) { listItemNumbers = } else if (i == options.pageTotal - 2) { listItemNumbers = } else { listItemNumbers = (j + 1) + '-' + (j + 2); } } } if (i == 0) { pageSelector.find('.b-current').text(listItemNumbers); }
// get the title listItemTitle = pages[i].title; if (listItemTitle == ) { listItemTitle = pages[i + 1].title; }
// get title for reversed direction if (options.direction == directions.rightToLeft) { listItemTitle = pages[Math.abs(i - options.pageTotal) - 1].title; if (listItemTitle == ) { listItemTitle = pages[Math.abs(i - options.pageTotal) - 2].title; } }
// add the list itempageListItem = $('
for (i = 0; i < options.pageTotal; i += 1) { if (pages[i].chapter != "" && typeof pages[i].chapter != "undefined") { if (options.direction == directions.rightToLeft) { j = i; if (j % 2 != 0) { j--; } chapterSelector.find('.b-current').text(pages[i].chapter);chapterListItem = $('
}
// force no overlays if using manual controls if (options.manual && $.ui) { options.overlays = false; }
// remove old item actions and references if (customN) { customN.off('click.booklet'); customN = null; } if (customP) { customP.off('click.booklet'); customP = null; }
// add overlays overlaysB = target.find('.b-overlay'); if (options.overlays && overlaysB.length == 0) {overlayP = $('').appendTo(ctrls); overlayN = $('').appendTo(ctrls);
overlaysB = target.find('.b-overlay'); } else if (!options.overlays) { overlaysB.remove(); overlaysB = null; }
// add tabs tabs = target.find('.b-tab'); if (options.tabs && tabs.length == 0) {tabP = $('
tabs = target.find('.b-tab'); } else if (!options.tabs) { target.css({ 'marginTop': 0 }); tabs.remove(); tabs = null; }
// update tab css, options might have changed if (options.tabs && tabs.length > 0) { if (options.tabWidth) { tabs.width(options.tabWidth); } if (options.tabHeight) { tabs.height(options.tabHeight); }
tabs.css({ 'top': '-' + tabN.outerHeight() + 'px' }); target.css({ 'marginTop': tabN.outerHeight() });
// update control titles for RTL direction if (options.direction == directions.rightToLeft) { tabN.html(options.previousControlText).attr('title', options.previousControlTitle); tabP.html(options.nextControlText).attr('title', options.nextControlTitle); } }
// add arrows arrows = target.find('.b-arrow'); if (options.arrows && arrows.length == 0) {arrowP = $('
arrows = target.find('.b-arrow');
// update control titles for RTL direction if (options.direction == directions.rightToLeft) {arrowN.html('
} } else if (!options.arrows) { arrows.remove(); arrows = null; }
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // ADD CONTROL ACTIONS /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// save all "b-prev" and "b-next" controls ctrlsN = ctrls.find('.b-next'); ctrlsP = ctrls.find('.b-prev');
// reset all bound events ctrlsN.off(".booklet"); ctrlsP.off(".booklet");
// add click actions ctrlsN.on('click.booklet', function (e) { e.preventDefault(); next(); }); ctrlsP.on('click.booklet', function (e) { e.preventDefault(); prev(); });
// add click action to custom controls if (options.next && $(options.next).length > 0) { customN = $(options.next); customN.on('click.booklet', function (e) { e.preventDefault(); next(); }); } if (options.prev && $(options.prev).length > 0) { customP = $(options.prev); customP.on('click.booklet', function (e) { e.preventDefault(); prev(); }); }
// add page hover animations if (options.overlays && options.hovers) { // hovers to start draggable forward ctrlsN.on("mouseover.booklet",function () { startHoverAnimation(true); }).on("mouseout.booklet", function () { endHoverAnimation(true); });
// hovers to start draggable backwards ctrlsP.on("mouseover.booklet",function () { startHoverAnimation(false); }).on("mouseout.booklet", function () { endHoverAnimation(false); }); }
// add arrow animations if (options.arrows) { if (options.arrowsHide) { if ($.support.opacity) { ctrlsN.on('mouseover.booklet',function () { arrowN.find('div').stop().fadeTo('fast', 1); }).on('mouseout.booklet', function () { arrowN.find('div').stop().fadeTo('fast', 0); }); ctrlsP.on('mouseover.booklet',function () { arrowP.find('div').stop().fadeTo('fast', 1); }).on('mouseout.booklet', function () { arrowP.find('div').stop().fadeTo('fast', 0); }); } else { ctrlsN.on('mouseover.booklet',function () { arrowN.find('div').show(); }).on('mouseout.booklet', function () { arrowN.find('div').hide(); }); ctrlsP.on('mouseover.booklet',function () { arrowP.find('div').show(); }).on('mouseout.booklet', function () { arrowP.find('div').hide(); }); } } else { arrowN.find('div').show(); arrowP.find('div').show(); } }
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// keyboard controls $(document).on('keyup.booklet', function (event) { if (event.keyCode == 37 && options.keyboard) { prev(); } else if (event.keyCode == 39 && options.keyboard) { next(); } });
// hash controls clearInterval(h); h = null; if (options.hash) { initHash(); clearInterval(h); h = setInterval(function () { pollHash() }, 250); }
// percentage resizing $(window).on('resize.booklet', function () { if ((wPercent || hPercent)) { updatePercentageSize(); } });
// auto flip book controls if (options.auto && options.delay) { clearInterval(a); a = setInterval(function () { if (options.direction == directions.leftToRight) { next(); } else { prev(); } }, options.delay); isPlaying = true;
if (options.pause && $(options.pause).length > 0) { pause = $(options.pause); pause.off('click.booklet') .on('click.booklet', function (e) { e.preventDefault(); if (isPlaying) { clearInterval(a); isPlaying = false; } }); }
if (options.play && $(options.play).length > 0) { play = $(options.play); play.off('click.booklet') .on('click.booklet', function (e) { e.preventDefault(); if (!isPlaying) { clearInterval(a); a = setInterval(function () { if (options.direction == directions.leftToRight) { next(); } else { prev(); } }, options.delay); isPlaying = true; } }); } } else { clearInterval(a); a = null; if (options.pause && $(options.pause).length > 0) { $(options.pause).off('click.booklet'); } pause = null; if (options.play && $(options.play).length > 0) { $(options.play).off('click.booklet'); } play = null; isPlaying = false; }
// if options were updated force pages, controls and menu to update if (didUpdate) { updatePages(); updateControlVisibility(); updateMenu(); } }, updateCSSandAnimations = function () { // init base css css = { wrap: { left: 0, width: pWidth - (options.pagePadding * 2) - (options.pageBorder * 2), height: pHeight - (options.pagePadding * 2) - (options.pageBorder * 2), padding: options.pagePadding }, p0wrap: { right: 0, left: 'auto' }, p1: { left: 0, width: pWidth, height: pHeight }, p2: { left: pWidth, width: pWidth, opacity: 1, height: pHeight }, pN: { left: 0, width: pWidth, height: pHeight }, p0: { left: 0, width: 0, height: pHeight }, p3: { left: pWidth * 2, width: 0, height: pHeight, paddingLeft: 0 }, p4: { left: pWidth, width: pWidth, height: pHeight }, sF: { right: 0, width: pWidth, height: pHeight }, sB: { left: 0, width: pWidth, height: pHeight } };
hoverShadowWidth = 10; hoverFullWidth = options.hoverWidth + hoverShadowWidth; hoverCurlWidth = (options.hoverWidth / 2) + hoverShadowWidth;
// init animation params anim = {
hover: { speed: options.hoverSpeed, size: options.hoverWidth,
p2: { width: pWidth - hoverCurlWidth }, p3: { left: options.width - hoverFullWidth, width: hoverCurlWidth }, p3closed: { left: pWidth - options.hoverWidth, width: hoverCurlWidth }, p3wrap: { left: hoverShadowWidth },
p2end: { width: pWidth }, p2closedEnd: { width: pWidth, left: 0 }, p3end: { left: options.width, width: 0 }, p3closedEnd: { left: pWidth, width: 0 }, p3wrapEnd: { left: 10 },
p1: { left: hoverCurlWidth, width: pWidth - hoverCurlWidth }, p1wrap: { left: '-' + hoverCurlWidth + 'px' }, p0: { left: hoverCurlWidth, width: hoverCurlWidth }, p0wrap: { right: hoverShadowWidth },
p1end: { left: 0, width: pWidth }, p1wrapEnd: { left: 0 }, p0end: { left: 0, width: 0 }, p0wrapEnd: { right: 0 } },
// forward p2: { width: 0 }, p2closed: { width: 0, left: pWidth }, p4closed: { left: pWidth }, p3in: { left: pWidthH, width: pWidthH, paddingLeft: options.shadowBtmWidth }, p3inDrag: { left: pWidth / 4, width: pWidth * .75, paddingLeft: options.shadowBtmWidth }, p3out: { left: 0, width: pWidth, paddingLeft: 0 }, p3wrapIn: { left: options.shadowBtmWidth }, p3wrapOut: { left: 0 },
// backwards p1: { left: pWidth, width: 0 }, p1wrap: { left: pWidthN }, p0: { left: pWidth, width: pWidth }, p0in: { left: pWidthH, width: pWidthH }, p0out: { left: pWidth, width: pWidth }, p0outClosed: { left: 0, width: pWidth }, p2back: { left: 0 }, p0wrapDrag: { right: 0 }, p0wrapIn: { right: options.shadowBtmWidth }, p0wrapOut: { right: 0 } }; }, updatePercentageSize = function () { if (!isDisabled) { // recalculate size for percentage values, called with window is resized if (wPercent) { options.width = (wOrig.replace('%', ) / 100) * parseFloat(target.parent().css('width')); target.width(options.width); pWidth = options.width / 2; pWidthN = '-' + (pWidth) + 'px'; pWidthH = pWidth / 2; } if (hPercent) { options.height = (hOrig.replace('%', ) / 100) * parseFloat(target.parent().css('height')); target.height(options.height); pHeight = options.height; } updateCSSandAnimations(); updatePageCSS(); } }, updateControlVisibility = function () { // update controls, cursors and visibility if (options.overlays || options.tabs || options.arrows) { if ($.support.opacity) { if (options.currentIndex >= 2 && options.currentIndex != 0) { ctrlsP.fadeIn('fast').css('cursor', options.cursor); } else { ctrlsP.fadeOut('fast').css('cursor', 'default'); } if (options.currentIndex < options.pageTotal - 2) { ctrlsN.fadeIn('fast').css('cursor', options.cursor); } else { ctrlsN.fadeOut('fast').css('cursor', 'default'); } } else { if (options.currentIndex >= 2 && options.currentIndex != 0) { ctrlsP.show().css('cursor', options.cursor); } else { ctrlsP.hide().css('cursor', 'default'); } if (options.currentIndex < options.pageTotal - 2) { ctrlsN.show().css('cursor', options.cursor); } else { ctrlsN.hide().css('cursor', 'default'); } } } }, updateMenu = function () { if (options.pageSelector) { var currentPageNumbers = ; if (options.direction == directions.rightToLeft) { currentPageNumbers = (Math.abs(options.currentIndex - options.pageTotal) - 1) + ' - ' + ((Math.abs(options.currentIndex - options.pageTotal))); if (options.closed) { if (options.currentIndex == options.pageTotal - 2) { currentPageNumbers = '1' } else if (options.currentIndex == 0) { currentPageNumbers = options.pageTotal - 2 } else { currentPageNumbers = (Math.abs(options.currentIndex - options.pageTotal) - 2) + ' - ' + ((Math.abs(options.currentIndex - options.pageTotal) - 1)); }
if (options.covers) { if (options.currentIndex == options.pageTotal - 2) { currentPageNumbers = } else if (options.currentIndex == 0) { currentPageNumbers = } else { currentPageNumbers = (Math.abs(options.currentIndex - options.pageTotal) - 3) + ' - ' + ((Math.abs(options.currentIndex - options.pageTotal) - 2)); } } } } else { currentPageNumbers = (options.currentIndex + 1) + ' - ' + (options.currentIndex + 2); if (options.closed) { if (options.currentIndex == 0) { currentPageNumbers = '1' } else if (options.currentIndex == options.pageTotal - 2) { currentPageNumbers = options.pageTotal - 2 } else { currentPageNumbers = (options.currentIndex) + '-' + (options.currentIndex + 1); }
if (options.covers) { if (options.currentIndex == 0) { currentPageNumbers = } else if (options.currentIndex == options.pageTotal - 2) { currentPageNumbers = } else { currentPageNumbers = (options.currentIndex - 1) + '-' + (options.currentIndex); } } } } $(options.menu + ' .b-selector-page .b-current').text(currentPageNumbers); } if (options.chapterSelector) { if (pages[options.currentIndex].chapter != "") { $(options.menu + ' .b-selector-chapter .b-current').text(pages[options.currentIndex].chapter); } else if (pages[options.currentIndex + 1].chapter != "") { $(options.menu + ' .b-selector-chapter .b-current').text(pages[options.currentIndex + 1].chapter); }
if (options.direction == directions.rightToLeft && pages[options.currentIndex + 1].chapter != "") { $(options.menu + ' .b-selector-chapter .b-current').text(pages[options.currentIndex + 1].chapter); } else if (pages[options.currentIndex] != "") { $(options.menu + ' .b-selector-chapter .b-current').text(pages[options.currentIndex].chapter); } } }, updateManualControls = function () { var origX, newX, diff, fullPercent, shadowPercent, shadowW, curlW, underW, targetPercent, curlLeft, p1wrapLeft;
// reset vars isHoveringRight = isHoveringLeft = p3drag = p0drag = false;
if ($.ui) { // manual page turning, check if jQuery UI is loaded if (target.find('.b-page').draggable()) { target.find('.b-page').draggable('destroy').removeClass('b-grab b-grabbing'); } if (options.manual) { // implement draggable forward p3.draggable({ axis: "x", containment: [ target.offset().left, 0, p2.offset().left + pWidth - hoverFullWidth, pHeight ], drag: function (event, ui) { p3drag = true; p3.removeClass('b-grab').addClass('b-grabbing');
// calculate positions origX = ui.originalPosition.left; newX = ui.position.left; diff = origX - newX; fullPercent = diff / origX; shadowPercent = fullPercent < 0.5 ? fullPercent : (1 - fullPercent); shadowW = (shadowPercent * options.shadowBtmWidth * 2) + hoverShadowWidth; shadowW = diff / origX >= 0.5 ? shadowW -= hoverShadowWidth : shadowW;
// move shadows if (options.shadows) { sF.css({'right': '-' + (options.shadowTopFwdWidth * shadowPercent * 2) + 'px'}); if ($.support.opacity) { sF.css({'opacity': shadowPercent * 2}); } else { sF.css({'right': 'auto', 'left': 0.1 * p3.width()}); } }
// set top page curl width curlW = hoverCurlWidth + diff / 2; curlW = curlW > pWidth ? pWidth : curlW; // constrain max width
// set bottom page width, hide underW = pWidth - curlW;
// calculate positions for closed and auto-centered book if (options.closed && options.autoCenter) { if (options.currentIndex == 0) { targetPercent = 0.5 + 0.5 * fullPercent; curlW = hoverCurlWidth + (hoverCurlWidth * fullPercent) + diff; curlW = curlW > pWidth ? pWidth : curlW; underW = pWidth - curlW;
p2.css({left: pWidth * fullPercent}); p4.css({left: pWidth * fullPercent}); target.width(options.width * targetPercent); } else if (options.currentIndex == options.pageTotal - 4) { targetPercent = (1 - fullPercent) + 0.5 * fullPercent; underW = pWidth - curlW;
p4.hide(); target.width(options.width * targetPercent); } else { target.width(options.width); } }
// set values p3.width(curlW); p3wrap.css({left: shadowW}); p2.width(underW); }, stop: function () { endHoverAnimation(false); if (fullPercent > options.hoverThreshold) { if (options.shadows && !$.support.opacity) { sF.css({'left': 'auto', opacity: 0}); } next(); p3.removeClass('b-grab b-grabbing'); } else { p3drag = false; p3.removeClass('b-grabbing').addClass('b-grab');
sF.animate({left: 'auto', opacity: 0}, anim.hover.speed, options.easing).css(css.sF);
if (options.closed && options.autoCenter) { if (options.currentIndex == 0) { p2.animate({left: 0}, anim.hover.speed, options.easing); p4.animate({left: 0}, anim.hover.speed, options.easing); target.animate({width: options.width * 0.5}, anim.hover.speed, options.easing); } else { target.animate({width: options.width}, anim.hover.speed, options.easing); } } } } });
// implement draggable backwards p0.draggable({ axis: "x", //containment: 'parent', containment: [ target.offset().left + hoverCurlWidth, 0, target.offset().left + options.width, pHeight ], drag: function (event, ui) { p0drag = true; p0.removeClass('b-grab').addClass('b-grabbing');
// calculate positions origX = ui.originalPosition.left; newX = ui.position.left; diff = newX - origX; fullPercent = diff / (options.width - origX); if (options.closed && options.autoCenter && options.currentIndex == 2) { fullPercent = diff / (pWidth - origX); } if (fullPercent > 1) { fullPercent = 1; }
shadowPercent = fullPercent < 0.5 ? fullPercent : (1 - fullPercent); shadowW = (shadowPercent * options.shadowBtmWidth * 2) + hoverShadowWidth; shadowW = diff / origX >= 0.5 ? shadowW -= hoverShadowWidth : shadowW;
if (options.shadows) { if ($.support.opacity) { sB.css({'opacity': shadowPercent * 2}); } else { sB.css({'left': options.shadowTopBackWidth * shadowPercent * 2}); } }
curlW = fullPercent * (pWidth - hoverCurlWidth) + hoverCurlWidth + shadowW; curlLeft = curlW - shadowW; p1wrapLeft = -curlLeft;
// calculate positions for closed and auto-centered book if (options.closed && options.autoCenter) { if (options.currentIndex == 2) { targetPercent = (1 - fullPercent) + 0.5 * fullPercent; curlLeft = (1 - fullPercent) * curlLeft; p1wrapLeft = -curlLeft - (options.width - (options.width * targetPercent)); pN.hide(); p2.css({left: pWidth * (1 - fullPercent)}); p4.css({left: pWidth * (1 - fullPercent)}); target.width(options.width * targetPercent); } else if (options.currentIndex == options.pageTotal - 2) { targetPercent = 0.5 + 0.5 * fullPercent; target.width(options.width * targetPercent); } else { target.width(options.width); } }
// set values ui.position.left = curlLeft; p0.css({width: curlW}); p0wrap.css({right: shadowW}); p1.css({left: curlLeft, width: pWidth - curlLeft}); p1wrap.css({left: p1wrapLeft}); }, stop: function () { endHoverAnimation(true); if (fullPercent > options.hoverThreshold) { prev(); p0.removeClass('b-grab b-grabbing'); } else { sB.animate({opacity: 0}, anim.hover.speed, options.easing).css(css.sB); p0drag = false; p0.removeClass('b-grabbing').addClass('b-grab');
if (options.closed && options.autoCenter) { if (options.currentIndex == 2) { p2.animate({left: pWidth}, anim.hover.speed * 2, options.easing); p4.animate({left: pWidth}, anim.hover.speed * 2, options.easing); target.animate({width: options.width}, anim.hover.speed * 2, options.easing); } else if (options.currentIndex == options.pageTotal - 2) { target.animate({width: options.width * 0.5}, anim.hover.speed, options.easing); } } } } });
target.find('.b-page').off('click.booklet'); if (options.hoverClick) { target.find('.b-pN, .b-p0').on('click.booklet', prev).css({cursor: 'pointer'}); target.find('.b-p3, .b-p4').on('click.booklet', next).css({cursor: 'pointer'}); }
// mouse tracking for page movement target.off('mousemove.booklet').on('mousemove.booklet',function (e) { diff = e.pageX - target.offset().left; if (diff < anim.hover.size) { startHoverAnimation(false); } else if (diff > pWidth - anim.hover.size && options.currentIndex == 0 && options.autoCenter && options.closed) { startHoverAnimation(true); } else if (diff > anim.hover.size && diff <= options.width - anim.hover.size) { endHoverAnimation(false); endHoverAnimation(true); } else if (diff > options.width - anim.hover.size) { startHoverAnimation(true); } }).off('mouseleave.booklet').on('mouseleave.booklet', function () { endHoverAnimation(false); endHoverAnimation(true); });
} } }, initHash = function () { hash = getHashNum();
if (!isNaN(hash) && hash <= options.pageTotal - 1 && hash >= 0 && hash != ) { if ((hash % 2) != 0) { hash--; } options.currentIndex = hash; } else { updateHash(options.currentIndex + 1, options); }
currentHash = hash; }, pollHash = function () { hash = getHashNum();
// check page num if (!isNaN(hash) && hash <= options.pageTotal - 1 && hash >= 0) { if (hash != options.currentIndex && hash.toString() != currentHash) { if ((hash % 2) != 0) { hash-- }
document.title = options.name + options.hashTitleText + (hash + 1);
if (!isBusy) { goToPage(hash); currentHash = hash; } } } }, getHashNum = function () { var hash, hashNum; // get page number from hash tag, last element hash = window.location.hash.split('/'); if (hash.length > 1) { hashNum = parseInt(hash[2]) - 1; if (options.direction == directions.rightToLeft) { hashNum = Math.abs(hashNum + 1 - options.pageTotal); } return hashNum; } else { return ; } }, updateHash = function (hash, options) { // set the hash if (options.hash) { if (options.direction == directions.rightToLeft) { hash = Math.abs(hash - options.pageTotal); } window.location.hash = hashRoot + hash; } }, destroyControls = function () {
if (options.menu) { $(options.menu).removeClass('b-menu');
if (options.pageSelector) { menu.find('.b-selector-page').remove(); pageSelector = pageSelectorList = listItemNumbers = listItemTitle = pageListItem = pageSelectorHeight = null; } if (options.chapterSelector) { menu.find('.b-selector-chapter').remove(); chapter = chapterSelector = chapterSelectorList = chapterListItem = chapterSelectorHeight = null; } } menu = null;
if (customN) { customN.off('click.booklet'); customN = null; }
if (customP) { customP.off('click.booklet'); customP = null; }
if (ctrlsN) { ctrlsN.off(".booklet"); ctrlsN = null; } if (ctrlsP) { ctrlsP.off(".booklet"); ctrlsP = null; }
target.find('.b-selector, .b-controls').remove();
// keyboard //$(document).off('keyup.booklet');
// hash clearInterval(h); h = null;
// window resize //$(window).off('resize.booklet');
// auto play clearInterval(a); a = null; if (options.pause && $(options.pause).length > 0) { $(options.pause).off('click.booklet'); } pause = null; if (options.play && $(options.play).length > 0) { $(options.play).off('click.booklet'); } play = null;
destroyManualControls(); }, destroyManualControls = function () { if ($.ui) { // remove old draggables if (target.find('.b-page').draggable()) { target.find('.b-page').draggable('destroy').removeClass('b-grab b-grabbing'); } } // remove mouse tracking for page movement target.off('.booklet'); },
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // DYNAMIC FUNCTIONS /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
addPage = function (index, html) { // validate inputs if (index == "start") { index = 0; } else if (index == "end") { index = originalPageTotal; } else if (typeof index == "number") { if (index < 0 || index > originalPageTotal) { return; } } else if (typeof index == "undefined") { return; }
if (typeof html == "undefined" || html == ) { return; }
// remove page structure, revert to original order destroyPages(); destroyControls();
// add new page if (options.closed && options.covers && index == originalPageTotal) { //end of closed-covers book target.children(':eq(' + (index - 1) + ')').before(html); } else if (options.closed && options.covers && index == 0) { //start of closed-covers book target.children(':eq(' + index + ')').after(html); } else if (index == originalPageTotal) { //end of book target.children(':eq(' + (index - 1) + ')').after(html); } else { target.children(':eq(' + index + ')').before(html); }
originalPageTotal = target.children().length;
// callback for adding page, returns options, index and the page node callback = { options: $.extend({}, options), index: index, page: target.children(':eq(' + index + ')')[0] }; if (options.add) { target.off(events.add + '.booklet').on(events.add + '.booklet', options.add); } target.trigger(events.add, callback);
// recall initialize functions initPages(); updateOptions(); updatePages(); updateControlVisibility(); updateMenu(); }, removePage = function (index) { // validate inputs if (index == "start") { index = 0; } else if (index == "end") { index = originalPageTotal; } else if (typeof index == "number") { if (index < 0 || index > originalPageTotal) { return; } } else if (typeof index == "undefined") { return; }
// stop if removing last remaining page if (target.children('.b-page').length == 2 && target.find('.b-page-blank').length > 0) { return; }
// remove page structure, revert to original order destroyPages(); destroyControls();
if (index >= options.currentIndex) { if (index > 0 && (index % 2) != 0) { options.currentIndex -= 2; } if (options.currentIndex < 0) { options.currentIndex = 0; } }
var removedPage;
// remove page if (options.closed && options.covers && index == originalPageTotal) { // end of closed-covers book removedPage = target.children(':eq(' + (index - 1) + ')').remove(); } else if (options.closed && options.covers && index == 0) { // start of closed-covers book removedPage = target.children(':eq(' + index + ')').remove(); } else if (index == originalPageTotal) { // end of book removedPage = target.children(':eq(' + (index - 1) + ')').remove(); } else { removedPage = target.children(':eq(' + index + ')').remove(); }
originalPageTotal = target.children().length;
// callback for removing page, returns options, index and the page node callback = { options: $.extend({}, options), index: index, page: removedPage[0] }; if (options.remove) { target.off(events.remove + '.booklet').on(events.remove + '.booklet', options.remove); } target.trigger(events.remove, callback);
removedPage = null;
// recall initialize functions initPages(); updatePages(); updateOptions(); updateControlVisibility(); updateMenu(); },
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // ANIMATION FUNCTIONS /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
next = function () { if (!isBusy && !isDisabled) { if (isPlaying && options.currentIndex + 2 >= options.pageTotal) { goToPage(0); } else { goToPage(options.currentIndex + 2); } } }, prev = function () { if (!isBusy && !isDisabled) { if (isPlaying && options.currentIndex - 2 < 0) { goToPage(options.pageTotal - 2); } else { goToPage(options.currentIndex - 2); } } }, goToPage = function (newIndex) { var speed;
if (newIndex < options.pageTotal && newIndex >= 0 && !isBusy && !isDisabled) { // moving forward (increasing number) if (newIndex > options.currentIndex) { isBusy = true; diff = newIndex - options.currentIndex; options.currentIndex = newIndex; options.movingForward = true;
// callback when starting booklet animation callback = { options: $.extend({}, options), index: newIndex, pages: [pages[newIndex].contentNode, pages[newIndex + 1].contentNode] }; if (options.start) { target.off(events.start + '.booklet').on(events.start + '.booklet', options.start); } target.trigger(events.start, callback);
updateMenu(); if (newIndex == options.pageTotal - 2) updateControlVisibility(); updateHash(options.currentIndex + 1, options);
// set animation speed, depending if user dragged any distance or not speed = p3drag === true ? options.speed * (p3.width() / pWidth) : speedH;
startPageAnimation(diff, true, sF, speed);
// hide p2 as p3 moves across it if (options.closed && options.autoCenter && newIndex - diff == 0) { p2.stop().animate(anim.p2closed, p3drag === true ? speed : speed * 2, options.easing); p4.stop().animate(anim.p4closed, p3drag === true ? speed : speed * 2, options.easing); } else { p2.stop().animate(anim.p2, speed, p3drag === true ? options.easeOut : options.easeIn); }
// if animating after a manual drag, calculate new speed and animate out if (p3drag) {
p3.animate(anim.p3out, speed, options.easeOut); p3wrap.animate(anim.p3wrapOut, speed, options.easeOut, function () { updateAfter() });
} else {
p3.stop().animate(anim.p3in, speed, options.easeIn) .animate(anim.p3out, speed, options.easeOut);
p3wrap.animate(anim.p3wrapIn, speed, options.easeIn) .animate(anim.p3wrapOut, speed, options.easeOut, function () { updateAfter() }); }
// moving backward (decreasing number) } else if (newIndex < options.currentIndex) { isBusy = true; diff = options.currentIndex - newIndex; options.currentIndex = newIndex; options.movingForward = false;
// callback when starting booklet animation callback = { options: $.extend({}, options), index: newIndex, pages: [pages[newIndex].contentNode, pages[newIndex + 1].contentNode] }; if (options.start) { target.off(events.start + '.booklet').on(events.start + '.booklet', options.start); } target.trigger(events.start, callback);
updateMenu(); if (newIndex == 0) updateControlVisibility(); updateHash(options.currentIndex + 1, options);
// set animation speed, depending if user dragged any distance or not speed = p0drag === true ? options.speed * (p0.width() / pWidth) : speedH;
startPageAnimation(diff, false, sB, speed);
if (p0drag) { // hide p1 as p0 moves across it p1.animate(anim.p1, speed, options.easeOut); p1wrap.animate(anim.p1wrap, speed, options.easeOut);
if (options.closed && options.autoCenter && options.currentIndex == 0) { p0.animate(anim.p0outClosed, speed, options.easeOut); p2.stop().animate(anim.p2back, speed, options.easeOut); } else { p0.animate(anim.p0, speed, options.easeOut); }
p0wrap.animate(anim.p0wrapDrag, speed, options.easeOut, function () { updateAfter() }); } else { // hide p1 as p0 moves across it p1.animate(anim.p1, speed * 2, options.easing); p1wrap.animate(anim.p1wrap, speed * 2, options.easing);
if (options.closed && options.autoCenter && options.currentIndex == 0) { p0.animate(anim.p0in, speed, options.easeIn) .animate(anim.p0outClosed, speed, options.easeOut); p2.stop().animate(anim.p2back, speed * 2, options.easing); } else { p0.animate(anim.p0in, speed, options.easeIn) .animate(anim.p0out, speed, options.easeOut); }
p0wrap.animate(anim.p0wrapIn, speed, options.easeIn) .animate(anim.p0wrapOut, speed, options.easeOut, function () { updateAfter() }); } } } }, startHoverAnimation = function (inc) { if (!isDisabled && ((options.hovers && options.overlays) || options.manual)) { if (inc) { if (!isBusy && !isHoveringRight && !isHoveringLeft && !p3drag && options.currentIndex + 2 <= options.pageTotal - 2) { // animate p2.stop().animate(anim.hover.p2, anim.hover.speed, options.easing); p3.addClass('b-grab'); if (options.closed && options.autoCenter && options.currentIndex == 0) { p3.stop().animate(anim.hover.p3closed, anim.hover.speed, options.easing); } else { p3.stop().animate(anim.hover.p3, anim.hover.speed, options.easing); } p3wrap.stop().animate(anim.hover.p3wrap, anim.hover.speed, options.easing); if (options.shadows && !$.support.opacity) { sF.css({ 'right': 'auto', 'left': '-40%' }); } isHoveringRight = true; } } else { if (!isBusy && !isHoveringLeft && !isHoveringRight && !p0drag && options.currentIndex - 2 >= 0) { // animate p1.stop().animate(anim.hover.p1, anim.hover.speed, options.easing); p0.addClass('b-grab'); p1wrap.stop().animate(anim.hover.p1wrap, anim.hover.speed, options.easing); p0.stop().animate(anim.hover.p0, anim.hover.speed, options.easing); p0wrap.stop().animate(anim.hover.p0wrap, anim.hover.speed, options.easing); if (options.shadows && !$.support.opacity) { sB.css({ 'left': -0.38 * pWidth }); } isHoveringLeft = true; } } } }, endHoverAnimation = function (inc) { if (!isDisabled && ((options.hovers && options.overlays) || options.manual)) { if (inc) { if (!isBusy && isHoveringRight && !p3drag && options.currentIndex + 2 <= options.pageTotal - 2) { if (options.closed && options.autoCenter && options.currentIndex == 0) { p2.stop().animate(anim.hover.p2closedEnd, anim.hover.speed, options.easing); p3.stop().animate(anim.hover.p3closedEnd, anim.hover.speed, options.easing); } else { p2.stop().animate(anim.hover.p2end, anim.hover.speed, options.easing); p3.stop().animate(anim.hover.p3end, anim.hover.speed, options.easing); } p3wrap.stop().animate(anim.hover.p3wrapEnd, anim.hover.speed, options.easing); if (options.shadows && !$.support.opacity) { sF.css({ 'left': 'auto' }); } isHoveringRight = false; } } else { if (!isBusy && isHoveringLeft && !p0drag && options.currentIndex - 2 >= 0) { p1.stop().animate(anim.hover.p1end, anim.hover.speed, options.easing); p1wrap.stop().animate(anim.hover.p1wrapEnd, anim.hover.speed, options.easing); p0.stop().animate(anim.hover.p0end, anim.hover.speed, options.easing); p0wrap.stop().animate(anim.hover.p0wrapEnd, anim.hover.speed, options.easing); isHoveringLeft = false; } } } }, startPageAnimation = function (diff, inc, shadow, speed) { // setup content if (inc && diff > 2) {
// initialize next 2 pages, if jumping forward in the book target.find('.b-p3, .b-p4').removeClass('b-p3 b-p4').hide(); target.find('.b-page-' + options.currentIndex).addClass('b-p3').show().stop().css(css.p3); target.find('.b-page-' + (options.currentIndex + 1)).addClass('b-p4').show().css(css.p4); target.find('.b-page-' + options.currentIndex + ' .b-wrap').show().css(css.wrap); target.find('.b-page-' + (options.currentIndex + 1) + ' .b-wrap').show().css(css.wrap);
p3 = target.find('.b-p3'); p4 = target.find('.b-p4'); p3wrap = target.find('.b-p3 .b-wrap'); p4wrap = target.find('.b-p4 .b-wrap');
if (options.closed && options.autoCenter && options.currentIndex - diff == 0) { p3.css({ 'left': pWidth }); p4.css({ 'left': 0 }); }
if (isHoveringRight) { p3.css({ 'left': options.width - 40, 'width': 20, 'padding-left': 10 }); }
if (options.shadows) { target.find('.b-shadow-f').remove(); sF = $(templates.sF).css(css.sF).appendTo(p3); shadow = sF; }
} else if (!inc && diff > 2) {
// initialize previous 2 pages, if jumping backwards in the book target.find('.b-pN, .b-p0').removeClass('b-pN b-p0').hide(); target.find('.b-page-' + options.currentIndex).addClass('b-pN').show().css(css.pN); target.find('.b-page-' + (options.currentIndex + 1)).addClass('b-p0').show().css(css.p0); target.find('.b-page-' + options.currentIndex + ' .b-wrap').show().css(css.wrap); target.find('.b-page-' + (options.currentIndex + 1) + ' .b-wrap').show().css(css.wrap);
pN = target.find('.b-pN'); p0 = target.find('.b-p0'); pNwrap = target.find('.b-pN .b-wrap'); p0wrap = target.find('.b-p0 .b-wrap');
if (options.closed && options.autoCenter) { pN.css({ 'left': 0 }); } p0wrap.css(css.p0wrap);
if (isHoveringLeft) { p0.css({ left: 10, width: 40 }); p0wrap.css({ right: 10 }); }
if (options.shadows) { target.find('.b-shadow-b, .b-shadow-f').remove(); sB = $(templates.sB).appendTo(p0).css(css.sB); shadow = sB; } }
// update page visibility // if moving to start and end of book if (options.closed) { if (!inc && options.currentIndex == 0) { pN.hide(); } else if (!inc) { pN.show(); } if (inc && options.currentIndex >= options.pageTotal - 2) { p4.hide(); } else if (inc) { p4.show(); } }
// init shadows if (options.shadows) { // check for opacity support -> animate shadow overlay on moving slide if ($.support.opacity) { if (!p3drag && !p0drag) { shadow.animate({ opacity: 1 }, speed, options.easeIn); } shadow.animate({ opacity: 0 }, speed, options.easeOut); } else { if (inc) { shadow.animate({ right: options.shadowTopFwdWidth }, speed * 2, options.easeIn); } else { shadow.animate({ left: options.shadowTopBackWidth }, speed * 2, options.easeIn); } } }
// init position animation if (options.closed && options.autoCenter) { if (options.currentIndex == 0) { p3.hide(); p4.hide(); target.animate({ width: pWidth }, !p3drag && !p0drag ? speed * 2 : speed, options.easing); } else if (options.currentIndex >= options.pageTotal - 2) { p0.hide(); pN.hide(); target.animate({ width: pWidth }, speed * 2, options.easing); } else { target.animate({ width: options.width }, speed * 2, options.easing); } }
}, updateAfter = function () { updatePages(); updateMenu(); updateControlVisibility(); isBusy = false;
// callback when ending booklet animation callback = { options: $.extend({}, options), index: options.currentIndex, pages: [pages[options.currentIndex].contentNode, pages[options.currentIndex + 1].contentNode] }; if (options.change) { target.off(events.change + '.booklet').on(events.change + '.booklet', options.change); } target.trigger(events.change, callback); };
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // PUBLIC FUNCTIONS /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
return { init: init, enable: enable, disable: disable, destroy: destroy, next: next, prev: prev, gotopage: function (index) { // validate inputs if (typeof index === 'string') { if (index == "start") { index = 0; } else if (index == "end") { index = options.pageTotal - 2; } else { this.gotopage(parseInt(index)); } } else if (typeof index === "number") { if (index < 0 || index >= options.pageTotal) { return; } } else if (typeof index === "undefined") { return; } // adjust for odd page if (index % 2 != 0) { index -= 1; } // adjust for booklet direction if (options.direction == directions.rightToLeft) { index = Math.abs(index - options.pageTotal) - 2; } goToPage(index); }, add: addPage, remove: removePage, option: function (name, value) { if (typeof name === 'string') { // if option exists if (typeof options[name] !== 'undefined') { if (typeof value !== 'undefined') { // if value is sent in, set the option value and update options options[name] = value; updateOptions(); } else { // if no value sent in, get the current option value return options[name]; } } else { $.error('Option "' + name + '" does not exist on jQuery.booklet.'); } } else if (typeof name === 'object') { // if sending in an object, update options updateOptions(name); } else if (typeof name === 'undefined' || !name) { // return a copy of the options object, to avoid changes return $.extend({}, options); } } } }
// define default options $.fn.booklet.defaults = { name: null, // name of the booklet to display in the document title bar width: 600, // container width height: 400, // container height speed: 1000, // speed of the transition between pages direction: 'LTR', // direction of the overall content organization, default LTR, left to right, can be RTL for languages which read right to left startingPage: 0, // index of the first page to be displayed easing: 'easeInOutQuad', // easing method for complete transition easeIn: 'easeInQuad', // easing method for first half of transition easeOut: 'easeOutQuad', // easing method for second half of transition
closed: false, // start with the book "closed", will add empty pages to beginning and end of book closedFrontTitle: 'Beginning', // used with "closed", "menu" and "pageSelector", determines title of blank starting page closedFrontChapter: 'Beginning of Book', // used with "closed", "menu" and "chapterSelector", determines chapter name of blank starting page closedBackTitle: 'End', // used with "closed", "menu" and "pageSelector", determines chapter name of blank ending page closedBackChapter: 'End of Book', // used with "closed", "menu" and "chapterSelector", determines chapter name of blank ending page covers: false, // used with "closed", makes first and last pages into covers, without page numbers (if enabled) autoCenter: false, // used with "closed", makes book position in center of container when closed
pagePadding: 10, // padding for each page wrapper pageNumbers: true, // display page numbers on each page pageBorder: 0, // size of the border around each page
manual: true, // enables manual page turning, requires jQuery UI to function hovers: true, // enables preview page-turn hover animation, shows a small preview of previous or next page on hover hoverWidth: 50, // default width for page-turn hover preview hoverSpeed: 500, // default speed for page-turn hover preview hoverThreshold: 0.25, // default percentage used for manual page dragging, sets the percentage amount a drag must be before moving next or prev hoverClick: true, // enables hovered arreas to be clicked when using manual page turning overlays: false, // enables navigation using a page sized overlay, when enabled links inside the content will not be clickable tabs: false, // adds tabs along the top of the pages tabWidth: 60, // set the width of the tabs tabHeight: 20, // set the height of the tabs nextControlText: 'Next', // inline text for all 'next' controls previousControlText: 'Previous', // inline text for all 'previous' controls nextControlTitle: 'Next Page', // text for title attributes of all 'next' controls previousControlTitle: 'Previous Page', // text for title attributes of all 'previous' controls arrows: false, // adds arrow overlays over the book edges arrowsHide: false, // auto hides arrows when controls are not hovered cursor: 'pointer', // cursor css setting for side bar areas
hash: false, // enables navigation using a hash string, ex: #/page/1 for page 1, will affect all booklets with 'hash' enabled hashTitleText: " - Page ", // text which forms the hash page title, ex: (Name)" - Page "(1) keyboard: true, // enables navigation with arrow keys (left: previous, right: next) next: null, // selector for element to use as click trigger for next page prev: null, // selector for element to use as click trigger for previous page auto: false, // enables automatic navigation, requires "delay" delay: 5000, // amount of time between automatic page flipping pause: null, // selector for element to use as click trigger for pausing auto page flipping play: null, // selector for element to use as click trigger for restarting auto page flipping
menu: null, // selector for element to use as the menu area, required for 'pageSelector' pageSelector: false, // enables navigation with a drop-down menu of pages, requires 'menu' chapterSelector: false, // enables navigation with a drop-down menu of chapters, determined by the "rel" attribute, requires 'menu'
shadows: true, // display shadows on page animations shadowTopFwdWidth: 166, // shadow width for top forward animation shadowTopBackWidth: 166, // shadow width for top back animation shadowBtmWidth: 50, // shadow width for bottom shadow
create: null, // called when booklet has been created start: null, // called when booklet starts to change pages change: null, // called when booklet has finished changing pages add: null, // called when booklet has added a page remove: null // called when booklet has removed a page }
})(jQuery);
/*
* jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/ * * Uses the built in easing capabilities added In jQuery 1.1 * to offer multiple easing options * * TERMS OF USE - jQuery Easing * * Open source under the BSD License. * * Copyright © 2008 George McGinley Smith * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. * * Neither the name of the author nor the names of contributors may be used to endorse * or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. *
- /
jQuery.easing['jswing']=jQuery.easing['swing'];jQuery.extend(jQuery.easing,{def:'easeOutQuad',swing:function(x,t,b,c,d){return jQuery.easing[jQuery.easing.def](x,t,b,c,d)},easeInQuad:function(x,t,b,c,d){return c*(t/=d)*t+b},easeOutQuad:function(x,t,b,c,d){return-c*(t/=d)*(t-2)+b},easeInOutQuad:function(x,t,b,c,d){if((t/=d/2)<1)return c/2*t*t+b;return-c/2*((--t)*(t-2)-1)+b},easeInCubic:function(x,t,b,c,d){return c*(t/=d)*t*t+b},easeOutCubic:function(x,t,b,c,d){return c*((t=t/d-1)*t*t+1)+b},easeInOutCubic:function(x,t,b,c,d){if((t/=d/2)<1)return c/2*t*t*t+b;return c/2*((t-=2)*t*t+2)+b},easeInQuart:function(x,t,b,c,d){return c*(t/=d)*t*t*t+b},easeOutQuart:function(x,t,b,c,d){return-c*((t=t/d-1)*t*t*t-1)+b},easeInOutQuart:function(x,t,b,c,d){if((t/=d/2)<1)return c/2*t*t*t*t+b;return-c/2*((t-=2)*t*t*t-2)+b},easeInQuint:function(x,t,b,c,d){return c*(t/=d)*t*t*t*t+b},easeOutQuint:function(x,t,b,c,d){return c*((t=t/d-1)*t*t*t*t+1)+b},easeInOutQuint:function(x,t,b,c,d){if((t/=d/2)<1)return c/2*t*t*t*t*t+b;return c/2*((t-=2)*t*t*t*t+2)+b},easeInSine:function(x,t,b,c,d){return-c*Math.cos(t/d*(Math.PI/2))+c+b},easeOutSine:function(x,t,b,c,d){return c*Math.sin(t/d*(Math.PI/2))+b},easeInOutSine:function(x,t,b,c,d){return-c/2*(Math.cos(Math.PI*t/d)-1)+b},easeInExpo:function(x,t,b,c,d){return(t==0)?b:c*Math.pow(2,10*(t/d-1))+b},easeOutExpo:function(x,t,b,c,d){return(t==d)?b+c:c*(-Math.pow(2,-10*t/d)+1)+b},easeInOutExpo:function(x,t,b,c,d){if(t==0)return b;if(t==d)return b+c;if((t/=d/2)<1)return c/2*Math.pow(2,10*(t-1))+b;return c/2*(-Math.pow(2,-10*--t)+2)+b},easeInCirc:function(x,t,b,c,d){return-c*(Math.sqrt(1-(t/=d)*t)-1)+b},easeOutCirc:function(x,t,b,c,d){return c*Math.sqrt(1-(t=t/d-1)*t)+b},easeInOutCirc:function(x,t,b,c,d){if((t/=d/2)<1)return-c/2*(Math.sqrt(1-t*t)-1)+b;return c/2*(Math.sqrt(1-(t-=2)*t)+1)+b},easeInElastic:function(x,t,b,c,d){var s=1.70158;var p=0;var a=c;if(t==0)return b;if((t/=d)==1)return b+c;if(!p)p=d*.3;if(a<Math.abs(c)){a=c;var s=p/4}else var s=p/(2*Math.PI)*Math.asin(c/a);return-(a*Math.pow(2,10*(t-=1))*Math.sin((t*d-s)*(2*Math.PI)/p))+b},easeOutElastic:function(x,t,b,c,d){var s=1.70158;var p=0;var a=c;if(t==0)return b;if((t/=d)==1)return b+c;if(!p)p=d*.3;if(a<Math.abs(c)){a=c;var s=p/4}else var s=p/(2*Math.PI)*Math.asin(c/a);return a*Math.pow(2,-10*t)*Math.sin((t*d-s)*(2*Math.PI)/p)+c+b},easeInOutElastic:function(x,t,b,c,d){var s=1.70158;var p=0;var a=c;if(t==0)return b;if((t/=d/2)==2)return b+c;if(!p)p=d*(.3*1.5);if(a<Math.abs(c)){a=c;var s=p/4}else var s=p/(2*Math.PI)*Math.asin(c/a);if(t<1)return-.5*(a*Math.pow(2,10*(t-=1))*Math.sin((t*d-s)*(2*Math.PI)/p))+b;return a*Math.pow(2,-10*(t-=1))*Math.sin((t*d-s)*(2*Math.PI)/p)*.5+c+b},easeInBack:function(x,t,b,c,d,s){if(s==undefined)s=1.70158;return c*(t/=d)*t*((s+1)*t-s)+b},easeOutBack:function(x,t,b,c,d,s){if(s==undefined)s=1.70158;return c*((t=t/d-1)*t*((s+1)*t+s)+1)+b},easeInOutBack:function(x,t,b,c,d,s){if(s==undefined)s=1.70158;if((t/=d/2)<1)return c/2*(t*t*(((s*=(1.525))+1)*t-s))+b;return c/2*((t-=2)*t*(((s*=(1.525))+1)*t+s)+2)+b},easeInBounce:function(x,t,b,c,d){return c-jQuery.easing.easeOutBounce(x,d-t,0,c,d)+b},easeOutBounce:function(x,t,b,c,d){if((t/=d)<(1/2.75)){return c*(7.5625*t*t)+b}else if(t<(2/2.75)){return c*(7.5625*(t-=(1.5/2.75))*t+.75)+b}else if(t<(2.5/2.75)){return c*(7.5625*(t-=(2.25/2.75))*t+.9375)+b}else{return c*(7.5625*(t-=(2.625/2.75))*t+.984375)+b}},easeInOutBounce:function(x,t,b,c,d){if(t<d/2)return jQuery.easing.easeInBounce(x,t*2,0,c,d)*.5+b;return jQuery.easing.easeOutBounce(x,t*2-d,0,c,d)*.5+c*.5+b}});