123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981 |
- /**
- * jQuery Galleriffic plugin
- *
- * Copyright (c) 2008 Trent Foley (http://trentacular.com)
- * Licensed under the MIT License:
- * http://www.opensource.org/licenses/mit-license.php
- *
- * Much thanks to primary contributer Ponticlaro (http://www.ponticlaro.com)
- *
- * Modifed by Jay Hayes (http://iamvery.com)
- */
- ;(function($) {
- // Globally keep track of all images by their unique hash. Each item is an image data object.
- var allImages = {};
- var imageCounter = 0;
- // Galleriffic static class
- $.galleriffic = {
- version: '2.0.3',
- // Strips invalid characters and any leading # characters
- normalizeHash: function(hash) {
- return hash.replace(/^.*#/, '').replace(/\?.*$/, '');
- },
- getImage: function(hash) {
- if (!hash)
- return undefined;
- hash = $.galleriffic.normalizeHash(hash);
- return allImages[hash];
- },
- // Global function that looks up an image by its hash and displays the image.
- // Returns false when an image is not found for the specified hash.
- // @param {String} hash This is the unique hash value assigned to an image.
- gotoImage: function(hash) {
- var imageData = $.galleriffic.getImage(hash);
- if (!imageData)
- return false;
- var gallery = imageData.gallery;
- gallery.gotoImage(imageData);
-
- return true;
- },
- // Removes an image from its respective gallery by its hash.
- // Returns false when an image is not found for the specified hash or the
- // specified owner gallery does match the located images gallery.
- // @param {String} hash This is the unique hash value assigned to an image.
- // @param {Object} ownerGallery (Optional) When supplied, the located images
- // gallery is verified to be the same as the specified owning gallery before
- // performing the remove operation.
- removeImageByHash: function(hash, ownerGallery) {
- var imageData = $.galleriffic.getImage(hash);
- if (!imageData)
- return false;
- var gallery = imageData.gallery;
- if (ownerGallery && ownerGallery != gallery)
- return false;
- return gallery.removeImageByIndex(imageData.index);
- }
- };
- var defaults = {
- delay: 3000,
- numThumbs: 20,
- preloadAhead: 40, // Set to -1 to preload all images
- enableTopPager: false,
- enableBottomPager: true,
- maxPagesToShow: 7,
- imageContainerSel: '',
- captionContainerSel: '',
- ssControlsContainerSel: '',
- navControlsContainerSel: '',
- loadingContainerSel: '',
- playLinkText: 'Play',
- pauseLinkText: 'Pause',
- prevLinkText: 'Previous',
- nextLinkText: 'Next',
- nextPageLinkText: 'Next ›',
- prevPageLinkText: '‹ Prev',
- enableHistory: false,
- enableKeyboardNavigation: true,
- autoStart: false,
- syncTransitions: false,
- defaultTransitionDuration: 1000,
- onSlideChange: undefined, // accepts a delegate like such: function(prevIndex, nextIndex) { ... }
- onTransitionOut: undefined, // accepts a delegate like such: function(slide, caption, isSync, callback) { ... }
- onTransitionIn: undefined, // accepts a delegate like such: function(slide, caption, isSync) { ... }
- onPageTransitionOut: undefined, // accepts a delegate like such: function(callback) { ... }
- onPageTransitionIn: undefined, // accepts a delegate like such: function() { ... }
- onImageAdded: undefined, // accepts a delegate like such: function(imageData, $li) { ... }
- onImageRemoved: undefined // accepts a delegate like such: function(imageData, $li) { ... }
- };
- // Primary Galleriffic initialization function that should be called on the thumbnail container.
- $.fn.galleriffic = function(settings) {
- // Extend Gallery Object
- $.extend(this, {
- // Returns the version of the script
- version: $.galleriffic.version,
- // Current state of the slideshow
- isSlideshowRunning: false,
- slideshowTimeout: undefined,
- // This function is attached to the click event of generated hyperlinks within the gallery
- clickHandler: function(e, link) {
- this.pause();
- if (!this.enableHistory) {
- // The href attribute holds the unique hash for an image
- var hash = $.galleriffic.normalizeHash($(link).attr('href'));
- $.galleriffic.gotoImage(hash);
- e.preventDefault();
- }
- },
- // Appends an image to the end of the set of images. Argument listItem can be either a jQuery DOM element or arbitrary html.
- // @param listItem Either a jQuery object or a string of html of the list item that is to be added to the gallery.
- appendImage: function(listItem) {
- this.addImage(listItem, false, false);
- return this;
- },
- // Inserts an image into the set of images. Argument listItem can be either a jQuery DOM element or arbitrary html.
- // @param listItem Either a jQuery object or a string of html of the list item that is to be added to the gallery.
- // @param {Integer} position The index within the gallery where the item shouold be added.
- insertImage: function(listItem, position) {
- this.addImage(listItem, false, true, position);
- return this;
- },
- // Adds an image to the gallery and optionally inserts/appends it to the DOM (thumbExists)
- // @param listItem Either a jQuery object or a string of html of the list item that is to be added to the gallery.
- // @param {Boolean} thumbExists Specifies whether the thumbnail already exists in the DOM or if it needs to be added.
- // @param {Boolean} insert Specifies whether the the image is appended to the end or inserted into the gallery.
- // @param {Integer} position The index within the gallery where the item shouold be added.
- addImage: function(listItem, thumbExists, insert, position) {
- var $li = ( typeof listItem === "string" ) ? $(listItem) : listItem;
- var $aThumb = $li.find('a.thumb');
- var slideUrl = $aThumb.attr('href');
- var title = $aThumb.attr('title');
- var $caption = $li.find('.caption').remove();
- var hash = $aThumb.attr('name');
- // Increment the image counter
- imageCounter++;
- // Autogenerate a hash value if none is present or if it is a duplicate
- if (!hash || allImages[''+hash]) {
- hash = imageCounter;
- }
- // Set position to end when not specified
- if (!insert)
- position = this.data.length;
-
- var imageData = {
- title:title,
- slideUrl:slideUrl,
- caption:$caption,
- hash:hash,
- gallery:this,
- index:position
- };
- // Add the imageData to this gallery's array of images
- if (insert) {
- this.data.splice(position, 0, imageData);
- // Reset index value on all imageData objects
- this.updateIndices(position);
- }
- else {
- this.data.push(imageData);
- }
- var gallery = this;
- // Add the element to the DOM
- if (!thumbExists) {
- // Update thumbs passing in addition post transition out handler
- this.updateThumbs(function() {
- var $thumbsUl = gallery.find('ul.thumbs');
- if (insert)
- $thumbsUl.children(':eq('+position+')').before($li);
- else
- $thumbsUl.append($li);
-
- if (gallery.onImageAdded)
- gallery.onImageAdded(imageData, $li);
- });
- }
- // Register the image globally
- allImages[''+hash] = imageData;
- // Setup attributes and click handler
- $aThumb.attr('rel', 'history')
- .attr('href', '#'+hash)
- .removeAttr('name')
- .click(function(e) {
- gallery.clickHandler(e, this);
- });
- return this;
- },
- // Removes an image from the gallery based on its index.
- // Returns false when the index is out of range.
- removeImageByIndex: function(index) {
- if (index < 0 || index >= this.data.length)
- return false;
-
- var imageData = this.data[index];
- if (!imageData)
- return false;
-
- this.removeImage(imageData);
-
- return true;
- },
- // Convenience method that simply calls the global removeImageByHash method.
- removeImageByHash: function(hash) {
- return $.galleriffic.removeImageByHash(hash, this);
- },
- // Removes an image from the gallery.
- removeImage: function(imageData) {
- var index = imageData.index;
-
- // Remove the image from the gallery data array
- this.data.splice(index, 1);
-
- // Remove the global registration
- delete allImages[''+imageData.hash];
-
- // Remove the image's list item from the DOM
- this.updateThumbs(function() {
- var $li = gallery.find('ul.thumbs')
- .children(':eq('+index+')')
- .remove();
- if (gallery.onImageRemoved)
- gallery.onImageRemoved(imageData, $li);
- });
- // Update each image objects index value
- this.updateIndices(index);
- return this;
- },
- // Updates the index values of the each of the images in the gallery after the specified index
- updateIndices: function(startIndex) {
- for (i = startIndex; i < this.data.length; i++) {
- this.data[i].index = i;
- }
-
- return this;
- },
- // Scraped the thumbnail container for thumbs and adds each to the gallery
- initializeThumbs: function() {
- this.data = [];
- var gallery = this;
- this.find('ul.thumbs > li').each(function(i) {
- gallery.addImage($(this), true, false);
- });
- return this;
- },
- isPreloadComplete: false,
- // Initalizes the image preloader
- preloadInit: function() {
- if (this.preloadAhead == 0) return this;
-
- this.preloadStartIndex = this.currentImage.index;
- var nextIndex = this.getNextIndex(this.preloadStartIndex);
- return this.preloadRecursive(this.preloadStartIndex, nextIndex);
- },
- // Changes the location in the gallery the preloader should work
- // @param {Integer} index The index of the image where the preloader should restart at.
- preloadRelocate: function(index) {
- // By changing this startIndex, the current preload script will restart
- this.preloadStartIndex = index;
- return this;
- },
- // Recursive function that performs the image preloading
- // @param {Integer} startIndex The index of the first image the current preloader started on.
- // @param {Integer} currentIndex The index of the current image to preload.
- preloadRecursive: function(startIndex, currentIndex) {
- // Check if startIndex has been relocated
- if (startIndex != this.preloadStartIndex) {
- var nextIndex = this.getNextIndex(this.preloadStartIndex);
- return this.preloadRecursive(this.preloadStartIndex, nextIndex);
- }
- var gallery = this;
- // Now check for preloadAhead count
- var preloadCount = currentIndex - startIndex;
- if (preloadCount < 0)
- preloadCount = this.data.length-1-startIndex+currentIndex;
- if (this.preloadAhead >= 0 && preloadCount > this.preloadAhead) {
- // Do this in order to keep checking for relocated start index
- setTimeout(function() { gallery.preloadRecursive(startIndex, currentIndex); }, 500);
- return this;
- }
- var imageData = this.data[currentIndex];
- if (!imageData)
- return this;
- // If already loaded, continue
- if (imageData.image)
- return this.preloadNext(startIndex, currentIndex);
-
- // Preload the image
- var image = new Image();
-
- image.onload = function() {
- imageData.image = this;
- gallery.preloadNext(startIndex, currentIndex);
- };
- image.alt = imageData.title;
- image.src = imageData.slideUrl;
- return this;
- },
-
- // Called by preloadRecursive in order to preload the next image after the previous has loaded.
- // @param {Integer} startIndex The index of the first image the current preloader started on.
- // @param {Integer} currentIndex The index of the current image to preload.
- preloadNext: function(startIndex, currentIndex) {
- var nextIndex = this.getNextIndex(currentIndex);
- if (nextIndex == startIndex) {
- this.isPreloadComplete = true;
- } else {
- // Use setTimeout to free up thread
- var gallery = this;
- setTimeout(function() { gallery.preloadRecursive(startIndex, nextIndex); }, 100);
- }
- return this;
- },
- // Safe way to get the next image index relative to the current image.
- // If the current image is the last, returns 0
- getNextIndex: function(index) {
- var nextIndex = index+1;
- if (nextIndex >= this.data.length)
- nextIndex = 0;
- return nextIndex;
- },
- // Safe way to get the previous image index relative to the current image.
- // If the current image is the first, return the index of the last image in the gallery.
- getPrevIndex: function(index) {
- var prevIndex = index-1;
- if (prevIndex < 0)
- prevIndex = this.data.length-1;
- return prevIndex;
- },
- // Pauses the slideshow
- pause: function() {
- this.isSlideshowRunning = false;
- if (this.slideshowTimeout) {
- clearTimeout(this.slideshowTimeout);
- this.slideshowTimeout = undefined;
- }
- if (this.$ssControlsContainer) {
- this.$ssControlsContainer
- .find('div.ss-controls a').removeClass().addClass('play')
- .attr('title', this.playLinkText)
- .attr('href', '#play')
- .html(this.playLinkText);
- }
-
- return this;
- },
- // Plays the slideshow
- play: function() {
- this.isSlideshowRunning = true;
- if (this.$ssControlsContainer) {
- this.$ssControlsContainer
- .find('div.ss-controls a').removeClass().addClass('pause')
- .attr('title', this.pauseLinkText)
- .attr('href', '#pause')
- .html(this.pauseLinkText);
- }
- if (!this.slideshowTimeout) {
- var gallery = this;
- this.slideshowTimeout = setTimeout(function() { gallery.ssAdvance(); }, this.delay);
- }
- return this;
- },
- // Toggles the state of the slideshow (playing/paused)
- toggleSlideshow: function() {
- if (this.isSlideshowRunning)
- this.pause();
- else
- this.play();
- return this;
- },
- // Advances the slideshow to the next image and delegates navigation to the
- // history plugin when history is enabled
- // enableHistory is true
- ssAdvance: function() {
- if (this.isSlideshowRunning)
- this.next(true);
- return this;
- },
- // Advances the gallery to the next image.
- // @param {Boolean} dontPause Specifies whether to pause the slideshow.
- // @param {Boolean} bypassHistory Specifies whether to delegate navigation to the history plugin when history is enabled.
- next: function(dontPause, bypassHistory) {
- this.gotoIndex(this.getNextIndex(this.currentImage.index), dontPause, bypassHistory);
- return this;
- },
- // Navigates to the previous image in the gallery.
- // @param {Boolean} dontPause Specifies whether to pause the slideshow.
- // @param {Boolean} bypassHistory Specifies whether to delegate navigation to the history plugin when history is enabled.
- previous: function(dontPause, bypassHistory) {
- this.gotoIndex(this.getPrevIndex(this.currentImage.index), dontPause, bypassHistory);
- return this;
- },
- // Navigates to the next page in the gallery.
- // @param {Boolean} dontPause Specifies whether to pause the slideshow.
- // @param {Boolean} bypassHistory Specifies whether to delegate navigation to the history plugin when history is enabled.
- nextPage: function(dontPause, bypassHistory) {
- var page = this.getCurrentPage();
- var lastPage = this.getNumPages() - 1;
- if (page < lastPage) {
- var startIndex = page * this.numThumbs;
- var nextPage = startIndex + this.numThumbs;
- this.gotoIndex(nextPage, dontPause, bypassHistory);
- }
- return this;
- },
- // Navigates to the previous page in the gallery.
- // @param {Boolean} dontPause Specifies whether to pause the slideshow.
- // @param {Boolean} bypassHistory Specifies whether to delegate navigation to the history plugin when history is enabled.
- previousPage: function(dontPause, bypassHistory) {
- var page = this.getCurrentPage();
- if (page > 0) {
- var startIndex = page * this.numThumbs;
- var prevPage = startIndex - this.numThumbs;
- this.gotoIndex(prevPage, dontPause, bypassHistory);
- }
-
- return this;
- },
- // Navigates to the image at the specified index in the gallery
- // @param {Integer} index The index of the image in the gallery to display.
- // @param {Boolean} dontPause Specifies whether to pause the slideshow.
- // @param {Boolean} bypassHistory Specifies whether to delegate navigation to the history plugin when history is enabled.
- gotoIndex: function(index, dontPause, bypassHistory) {
- if (!dontPause)
- this.pause();
-
- if (index < 0) index = 0;
- else if (index >= this.data.length) index = this.data.length-1;
-
- var imageData = this.data[index];
-
- if (!bypassHistory && this.enableHistory)
- $.history.load(String(imageData.hash)); // At the moment, history.load only accepts string arguments
- else
- this.gotoImage(imageData);
- return this;
- },
- // This function is garaunteed to be called anytime a gallery slide changes.
- // @param {Object} imageData An object holding the image metadata of the image to navigate to.
- gotoImage: function(imageData) {
- var index = imageData.index;
- // Prevent reloading same image
- if (this.currentImage && this.currentImage.index == index)
- return this;
- if (this.onSlideChange && this.currentImage)
- this.onSlideChange(this.currentImage.index, index);
-
- this.currentImage = imageData;
- this.preloadRelocate(index);
-
- this.refresh();
-
- return this;
- },
- // Returns the default transition duration value. The value is halved when not
- // performing a synchronized transition.
- // @param {Boolean} isSync Specifies whether the transitions are synchronized.
- getDefaultTransitionDuration: function(isSync) {
- if (isSync)
- return this.defaultTransitionDuration;
- return this.defaultTransitionDuration / 2;
- },
- // Rebuilds the slideshow image and controls and performs transitions
- refresh: function() {
- var imageData = this.currentImage;
- if (!imageData)
- return this;
- var index = imageData.index;
- // Update Controls
- if (this.$navControlsContainer) {
- this.$navControlsContainer
- .find('div.nav-controls a.prev').attr('href', '#'+this.data[this.getPrevIndex(index)].hash).end()
- .find('div.nav-controls a.next').attr('href', '#'+this.data[this.getNextIndex(index)].hash);
- }
- var previousSlide = this.$imageContainer.find('span.current').addClass('previous').removeClass('current');
- var previousCaption = 0;
- if (this.$captionContainer) {
- previousCaption = this.$captionContainer.find('span.current').addClass('previous').removeClass('current');
- }
- // Perform transitions simultaneously if syncTransitions is true and the next image is already preloaded
- var isSync = this.syncTransitions && imageData.image;
- // Flag we are transitioning
- var isTransitioning = true;
- var gallery = this;
- var transitionOutCallback = function() {
- // Flag that the transition has completed
- isTransitioning = false;
- // Remove the old slide
- previousSlide.remove();
- // Remove old caption
- if (previousCaption)
- previousCaption.remove();
- if (!isSync) {
- if (imageData.image && imageData.hash == gallery.data[gallery.currentImage.index].hash) {
- gallery.buildImage(imageData, isSync);
- } else {
- // Show loading container
- if (gallery.$loadingContainer) {
- gallery.$loadingContainer.show();
- }
- }
- }
- };
- if (previousSlide.length == 0) {
- // For the first slide, the previous slide will be empty, so we will call the callback immediately
- transitionOutCallback();
- } else {
- if (this.onTransitionOut) {
- this.onTransitionOut(previousSlide, previousCaption, isSync, transitionOutCallback);
- } else {
- previousSlide.fadeTo(this.getDefaultTransitionDuration(isSync), 0.0, transitionOutCallback);
- if (previousCaption)
- previousCaption.fadeTo(this.getDefaultTransitionDuration(isSync), 0.0);
- }
- }
- // Go ahead and begin transitioning in of next image
- if (isSync)
- this.buildImage(imageData, isSync);
- if (!imageData.image) {
- var image = new Image();
-
- // Wire up mainImage onload event
- image.onload = function() {
- imageData.image = this;
- // Only build image if the out transition has completed and we are still on the same image hash
- if (!isTransitioning && imageData.hash == gallery.data[gallery.currentImage.index].hash) {
- gallery.buildImage(imageData, isSync);
- }
- };
- // set alt and src
- image.alt = imageData.title;
- image.src = imageData.slideUrl;
- }
- // This causes the preloader (if still running) to relocate out from the currentIndex
- this.relocatePreload = true;
- return this.syncThumbs();
- },
- // Called by the refresh method after the previous image has been transitioned out or at the same time
- // as the out transition when performing a synchronous transition.
- // @param {Object} imageData An object holding the image metadata of the image to build.
- // @param {Boolean} isSync Specifies whether the transitions are synchronized.
- buildImage: function(imageData, isSync) {
- var gallery = this;
- var nextIndex = this.getNextIndex(imageData.index);
- // Construct new hidden span for the image
- var newSlide = this.$imageContainer
- .append('<span class="image-wrapper current"><a class="advance-link" rel="history" href="#'+this.data[nextIndex].hash+'" title="'+imageData.title+'"> </a></span>')
- .find('span.current').css('opacity', '0');
-
- newSlide.find('a')
- .append(imageData.image)
- .click(function(e) {
- gallery.clickHandler(e, this);
- });
-
- var newCaption = 0;
- if (this.$captionContainer) {
- // Construct new hidden caption for the image
- newCaption = this.$captionContainer
- .append('<span class="image-caption current"></span>')
- .find('span.current').css('opacity', '0')
- .append(imageData.caption);
- }
- // Hide the loading conatiner
- if (this.$loadingContainer) {
- this.$loadingContainer.hide();
- }
- // Transition in the new image
- if (this.onTransitionIn) {
- this.onTransitionIn(newSlide, newCaption, isSync);
- } else {
- newSlide.fadeTo(this.getDefaultTransitionDuration(isSync), 1.0);
- if (newCaption)
- newCaption.fadeTo(this.getDefaultTransitionDuration(isSync), 1.0);
- }
-
- if (this.isSlideshowRunning) {
- if (this.slideshowTimeout)
- clearTimeout(this.slideshowTimeout);
- this.slideshowTimeout = setTimeout(function() { gallery.ssAdvance(); }, this.delay);
- }
- return this;
- },
- // Returns the current page index that should be shown for the currentImage
- getCurrentPage: function() {
- return Math.floor(this.currentImage.index / this.numThumbs);
- },
- // Applies the selected class to the current image's corresponding thumbnail.
- // Also checks if the current page has changed and updates the displayed page of thumbnails if necessary.
- syncThumbs: function() {
- var page = this.getCurrentPage();
- if (page != this.displayedPage)
- this.updateThumbs();
- // Remove existing selected class and add selected class to new thumb
- var $thumbs = this.find('ul.thumbs').children();
- $thumbs.filter('.selected').removeClass('selected');
- $thumbs.eq(this.currentImage.index).addClass('selected');
- return this;
- },
- // Performs transitions on the thumbnails container and updates the set of
- // thumbnails that are to be displayed and the navigation controls.
- // @param {Delegate} postTransitionOutHandler An optional delegate that is called after
- // the thumbnails container has transitioned out and before the thumbnails are rebuilt.
- updateThumbs: function(postTransitionOutHandler) {
- var gallery = this;
- var transitionOutCallback = function() {
- // Call the Post-transition Out Handler
- if (postTransitionOutHandler)
- postTransitionOutHandler();
-
- gallery.rebuildThumbs();
- // Transition In the thumbsContainer
- if (gallery.onPageTransitionIn)
- gallery.onPageTransitionIn();
- else
- gallery.show();
- };
- // Transition Out the thumbsContainer
- if (this.onPageTransitionOut) {
- this.onPageTransitionOut(transitionOutCallback);
- } else {
- this.hide();
- transitionOutCallback();
- }
- return this;
- },
- // Updates the set of thumbnails that are to be displayed and the navigation controls.
- rebuildThumbs: function() {
- var needsPagination = this.data.length > this.numThumbs;
- // Rebuild top pager
- if (this.enableTopPager) {
- var $topPager = this.find('div.top');
- if ($topPager.length == 0)
- $topPager = this.prepend('<div class="top pagination"></div>').find('div.top');
- else
- $topPager.empty();
- if (needsPagination)
- this.buildPager($topPager);
- }
- // Rebuild bottom pager
- if (this.enableBottomPager) {
- var $bottomPager = this.find('div.bottom');
- if ($bottomPager.length == 0)
- $bottomPager = this.append('<div class="bottom pagination"></div>').find('div.bottom');
- else
- $bottomPager.empty();
- if (needsPagination)
- this.buildPager($bottomPager);
- }
- var page = this.getCurrentPage();
- var startIndex = page*this.numThumbs;
- var stopIndex = startIndex+this.numThumbs-1;
- if (stopIndex >= this.data.length)
- stopIndex = this.data.length-1;
- // Show/Hide thumbs
- var $thumbsUl = this.find('ul.thumbs');
- $thumbsUl.find('li').each(function(i) {
- var $li = $(this);
- if (i >= startIndex && i <= stopIndex) {
- $li.show();
- } else {
- $li.hide();
- }
- });
- this.displayedPage = page;
- // Remove the noscript class from the thumbs container ul
- $thumbsUl.removeClass('noscript');
-
- return this;
- },
- // Returns the total number of pages required to display all the thumbnails.
- getNumPages: function() {
- return Math.ceil(this.data.length/this.numThumbs);
- },
- // Rebuilds the pager control in the specified matched element.
- // @param {jQuery} pager A jQuery element set matching the particular pager to be rebuilt.
- buildPager: function(pager) {
- var gallery = this;
- var numPages = this.getNumPages();
- var page = this.getCurrentPage();
- var startIndex = page * this.numThumbs;
- var pagesRemaining = this.maxPagesToShow - 1;
-
- var pageNum = page - Math.floor((this.maxPagesToShow - 1) / 2) + 1;
- if (pageNum > 0) {
- var remainingPageCount = numPages - pageNum;
- if (remainingPageCount < pagesRemaining) {
- pageNum = pageNum - (pagesRemaining - remainingPageCount);
- }
- }
- if (pageNum < 0) {
- pageNum = 0;
- }
- // Prev Page Link
- if (page > 0) {
- var prevPage = startIndex - this.numThumbs;
- pager.append('<a rel="history" href="#'+this.data[prevPage].hash+'" title="'+this.prevPageLinkText+'">'+this.prevPageLinkText+'</a>');
- }
- // Create First Page link if needed
- if (pageNum > 0) {
- this.buildPageLink(pager, 0, numPages);
- if (pageNum > 1)
- pager.append('<span class="ellipsis">…</span>');
-
- pagesRemaining--;
- }
- // Page Index Links
- while (pagesRemaining > 0) {
- this.buildPageLink(pager, pageNum, numPages);
- pagesRemaining--;
- pageNum++;
- }
- // Create Last Page link if needed
- if (pageNum < numPages) {
- var lastPageNum = numPages - 1;
- if (pageNum < lastPageNum)
- pager.append('<span class="ellipsis">…</span>');
- this.buildPageLink(pager, lastPageNum, numPages);
- }
- // Next Page Link
- var nextPage = startIndex + this.numThumbs;
- if (nextPage < this.data.length) {
- pager.append('<a rel="history" href="#'+this.data[nextPage].hash+'" title="'+this.nextPageLinkText+'">'+this.nextPageLinkText+'</a>');
- }
- pager.find('a').click(function(e) {
- gallery.clickHandler(e, this);
- });
- return this;
- },
- // Builds a single page link within a pager. This function is called by buildPager
- // @param {jQuery} pager A jQuery element set matching the particular pager to be rebuilt.
- // @param {Integer} pageNum The page number of the page link to build.
- // @param {Integer} numPages The total number of pages required to display all thumbnails.
- buildPageLink: function(pager, pageNum, numPages) {
- var pageLabel = pageNum + 1;
- var currentPage = this.getCurrentPage();
- if (pageNum == currentPage)
- pager.append('<span class="current">'+pageLabel+'</span>');
- else if (pageNum < numPages) {
- var imageIndex = pageNum*this.numThumbs;
- pager.append('<a rel="history" href="#'+this.data[imageIndex].hash+'" title="'+pageLabel+'">'+pageLabel+'</a>');
- }
-
- return this;
- }
- });
- // Now initialize the gallery
- $.extend(this, defaults, settings);
-
- // Verify the history plugin is available
- if (this.enableHistory && !$.history)
- this.enableHistory = false;
-
- // Select containers
- if (this.imageContainerSel) this.$imageContainer = $(this.imageContainerSel);
- if (this.captionContainerSel) this.$captionContainer = $(this.captionContainerSel);
- if (this.loadingContainerSel) this.$loadingContainer = $(this.loadingContainerSel);
- // Initialize the thumbails
- this.initializeThumbs();
-
- if (this.maxPagesToShow < 3)
- this.maxPagesToShow = 3;
- this.displayedPage = -1;
- var gallery = this;
- // Hide the loadingContainer
- if (this.$loadingContainer)
- this.$loadingContainer.hide();
- // Setup controls
- if (this.ssControlsContainerSel) {
- this.$ssControlsContainer = $(this.ssControlsContainerSel).empty();
- if (this.autoStart) {
- this.$ssControlsContainer
- .append('<div class="ss-controls"><a href="#pause" class="pause" title="'+this.pauseLinkText+'">'+this.pauseLinkText+'</a></div>');
- } else {
- this.$ssControlsContainer
- .append('<div class="ss-controls"><a href="#play" class="play" title="'+this.playLinkText+'">'+this.playLinkText+'</a></div>');
- }
-
- this.$ssControlsContainer.find('div.ss-controls a')
- .click(function(e) {
- gallery.toggleSlideshow();
- e.preventDefault();
- return false;
- });
- }
-
- if (this.navControlsContainerSel) {
- this.$navControlsContainer = $(this.navControlsContainerSel).empty();
- this.$navControlsContainer
- .append('<div class="nav-controls"><a class="prev" rel="history" title="'+this.prevLinkText+'">'+this.prevLinkText+'</a><a class="next" rel="history" title="'+this.nextLinkText+'">'+this.nextLinkText+'</a></div>')
- .find('div.nav-controls a')
- .click(function(e) {
- gallery.clickHandler(e, this);
- });
- }
- var initFirstImage = !this.enableHistory || !location.hash;
- if (this.enableHistory && location.hash) {
- var hash = $.galleriffic.normalizeHash(location.hash);
- var imageData = allImages[hash];
- if (!imageData)
- initFirstImage = true;
- }
- // Setup gallery to show the first image
- if (initFirstImage)
- this.gotoIndex(0, false, true);
- // Setup Keyboard Navigation
- if (this.enableKeyboardNavigation) {
- $(document).keydown(function(e) {
- var key = e.charCode ? e.charCode : e.keyCode ? e.keyCode : 0;
- switch(key) {
- case 32: // space
- gallery.next();
- e.preventDefault();
- break;
- case 33: // Page Up
- gallery.previousPage();
- e.preventDefault();
- break;
- case 34: // Page Down
- gallery.nextPage();
- e.preventDefault();
- break;
- case 35: // End
- gallery.gotoIndex(gallery.data.length-1);
- e.preventDefault();
- break;
- case 36: // Home
- gallery.gotoIndex(0);
- e.preventDefault();
- break;
- case 37: // left arrow
- gallery.previous();
- e.preventDefault();
- break;
- case 39: // right arrow
- gallery.next();
- e.preventDefault();
- break;
- }
- });
- }
- // Auto start the slideshow
- if (this.autoStart)
- this.play();
- // Kickoff Image Preloader after 1 second
- setTimeout(function() { gallery.preloadInit(); }, 1000);
- return this;
- };
- })(jQuery);
|