(function ($) { var allImages = {}; var imageCounter = 0; $.galleriffic = { version: "2.0.1", normalizeHash: function (hash) { return hash.replace(/^.*#/, "").replace(/\?.*$/, "") }, getImage: function (hash) { if (!hash) { return undefined } hash = $.galleriffic.normalizeHash(hash); return allImages[hash] }, gotoImage: function (hash) { var imageData = $.galleriffic.getImage(hash); if (!imageData) { return false } var gallery = imageData.gallery; gallery.gotoImage(imageData); return true }, 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, enableTopPager: false, enableBottomPager: true, maxPagesToShow: 7, imageContainerSel: "", captionContainerSel: "", controlsContainerSel: "", loadingContainerSel: "", renderSSControls: true, renderNavControls: true, playLinkText: "Play", pauseLinkText: "Pause", prevLinkText: "Previous", nextLinkText: "Next", nextPageLinkText: "Next &rsaquo;", prevPageLinkText: "&lsaquo; Prev", enableHistory: false, enableKeyboardNavigation: true, autoStart: false, syncTransitions: false, defaultTransitionDuration: 1000, onSlideChange: undefined, onTransitionOut: undefined, onTransitionIn: undefined, onPageTransitionOut: undefined, onPageTransitionIn: undefined, onImageAdded: undefined, onImageRemoved: undefined }; $.fn.galleriffic = function (settings) { $.extend(this, { version: $.galleriffic.version, isSlideshowRunning: false, slideshowTimeout: undefined, clickHandler: function (e, link) { this.pause(); if (!this.enableHistory) { var hash = $.galleriffic.normalizeHash($(link).attr("href")); $.galleriffic.gotoImage(hash); e.preventDefault() } }, appendImage: function (listItem) { this.addImage(listItem, false, false); return this }, insertImage: function (listItem, position) { this.addImage(listItem, false, true, position); return this }, 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 = jQuery.trim($aThumb.attr("title")); var $caption = $li.find(".caption").remove(); var hash = $aThumb.attr("name"); imageCounter++; if (!hash || allImages["" + hash]) { hash = imageCounter } if (!insert) { position = this.data.length } var imageData = { title: title, slideUrl: slideUrl, caption: $caption, hash: hash, gallery: this, index: position }; if (insert) { this.data.splice(position, 0, imageData); this.updateIndices(position) } else { this.data.push(imageData) } var gallery = this; if (!thumbExists) { 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) } }) } allImages["" + hash] = imageData; $aThumb.attr("rel", "history").attr("href", "#" + hash).removeAttr("name").click(function (e) { gallery.clickHandler(e, this) }); return this }, 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 }, removeImageByHash: function (hash) { return $.galleriffic.removeImageByHash(hash, this) }, removeImage: function (imageData) { var index = imageData.index; this.data.splice(index, 1); delete allImages["" + imageData.hash]; this.updateThumbs(function () { var $li = gallery.find("ul.thumbs").children(":eq(" + index + ")").remove(); if (gallery.onImageRemoved) { gallery.onImageRemoved(imageData, $li) } }); this.updateIndices(index); return this }, updateIndices: function (startIndex) { for (i = startIndex; i < this.data.length; i++) { this.data[i].index = i } return this }, initializeThumbs: function () { this.data = []; var gallery = this; this.find("ul.thumbs > li").each(function (i) { gallery.addImage($(this), true, false) }); return this }, isPreloadComplete: false, 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) }, preloadRelocate: function (index) { this.preloadStartIndex = index; return this }, preloadRecursive: function (startIndex, currentIndex) { if (startIndex != this.preloadStartIndex) { var nextIndex = this.getNextIndex(this.preloadStartIndex); return this.preloadRecursive(this.preloadStartIndex, nextIndex) } var gallery = this; var preloadCount = currentIndex - startIndex; if (preloadCount < 0) { preloadCount = this.data.length - 1 - startIndex + currentIndex } if (this.preloadAhead >= 0 && preloadCount > this.preloadAhead) { setTimeout(function () { gallery.preloadRecursive(startIndex, currentIndex) }, 500); return this } var imageData = this.data[currentIndex]; if (!imageData) { return this } if (imageData.image) { return this.preloadNext(startIndex, currentIndex) } var image = new Image(); image.onload = function () { imageData.image = this; gallery.preloadNext(startIndex, currentIndex) }; image.alt = imageData.title; image.src = imageData.slideUrl; return this }, preloadNext: function (startIndex, currentIndex) { var nextIndex = this.getNextIndex(currentIndex); if (nextIndex == startIndex) { this.isPreloadComplete = true } else { var gallery = this; setTimeout(function () { gallery.preloadRecursive(startIndex, nextIndex) }, 100) } return this }, getNextIndex: function (index) { var nextIndex = index + 1; if (nextIndex >= this.data.length) { nextIndex = 0 } return nextIndex }, getPrevIndex: function (index) { var prevIndex = index - 1; if (prevIndex < 0) { prevIndex = this.data.length - 1 } return prevIndex }, pause: function () { this.isSlideshowRunning = false; if (this.slideshowTimeout) { clearTimeout(this.slideshowTimeout); this.slideshowTimeout = undefined } if (this.$controlsContainer) { this.$controlsContainer.find("div.ss-controls a").removeClass().addClass("play").attr("title", this.playLinkText).attr("href", "#play").html(this.playLinkText) } return this }, play: function () { this.isSlideshowRunning = true; if (this.$controlsContainer) { this.$controlsContainer.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 }, toggleSlideshow: function () { if (this.isSlideshowRunning) { this.pause() } else { this.play() } return this }, ssAdvance: function () { if (this.isSlideshowRunning) { this.next(true) } return this }, next: function (dontPause, bypassHistory) { this.gotoIndex(this.getNextIndex(this.currentImage.index), dontPause, bypassHistory); return this }, previous: function (dontPause, bypassHistory) { this.gotoIndex(this.getPrevIndex(this.currentImage.index), dontPause, bypassHistory); return this }, 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 }, 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 }, 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) { $.historyLoad(String(imageData.hash)) } else { this.gotoImage(imageData) } return this }, gotoImage: function (imageData) { var index = imageData.index; if (this.onSlideChange) { this.onSlideChange(this.currentImage.index, index) } this.currentImage = imageData; this.preloadRelocate(index); this.refresh(); return this }, getDefaultTransitionDuration: function (isSync) { if (isSync) { return this.defaultTransitionDuration } return this.defaultTransitionDuration / 2 }, refresh: function () { var imageData = this.currentImage; if (!imageData) { return this } var index = imageData.index; if (this.$controlsContainer) { this.$controlsContainer.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") } var isSync = this.syncTransitions && imageData.image; var isTransitioning = true; var gallery = this; var transitionOutCallback = function () { isTransitioning = false; previousSlide.remove(); if (previousCaption) { previousCaption.remove() } if (!isSync) { if (imageData.image && imageData.hash == gallery.data[gallery.currentImage.index].hash) { gallery.buildImage(imageData, isSync) } else { if (gallery.$loadingContainer) { gallery.$loadingContainer.show() } } } }; if (previousSlide.length == 0) { transitionOutCallback() } else { if (this.onTransitionOut) { this.onTransitionOut(previousSlide, previousCaption, isSync, transitionOutCallback) } else { previousSlide.fadeTo(this.getDefaultTransitionDuration(isSync), 0, transitionOutCallback); if (previousCaption) { previousCaption.fadeTo(this.getDefaultTransitionDuration(isSync), 0) } } } if (isSync) { this.buildImage(imageData, isSync) } if (!imageData.image) { var image = new Image(); image.onload = function () { imageData.image = this; if (!isTransitioning && imageData.hash == gallery.data[gallery.currentImage.index].hash) { gallery.buildImage(imageData, isSync) } }; image.alt = imageData.title; image.src = imageData.slideUrl } this.relocatePreload = true; return this.syncThumbs() }, buildImage: function (imageData, isSync) { var gallery = this; var nextIndex = this.getNextIndex(imageData.index); 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) { newCaption = this.$captionContainer.append('<span class="image-caption current"></span>').find("span.current").css("opacity", "0").append(imageData.caption) } if (this.$loadingContainer) { this.$loadingContainer.hide() } if (this.onTransitionIn) { this.onTransitionIn(newSlide, newCaption, isSync) } else { newSlide.fadeTo(this.getDefaultTransitionDuration(isSync), 1); if (newCaption) { newCaption.fadeTo(this.getDefaultTransitionDuration(isSync), 1) } } if (this.isSlideshowRunning) { if (this.slideshowTimeout) { clearTimeout(this.slideshowTimeout) } this.slideshowTimeout = setTimeout(function () { gallery.ssAdvance() }, this.delay) } return this }, getCurrentPage: function () { return Math.floor(this.currentImage.index / this.numThumbs) }, syncThumbs: function () { var page = this.getCurrentPage(); if (page != this.displayedPage) { this.updateThumbs() } var $thumbs = this.find("ul.thumbs").children(); $thumbs.filter(".selected").removeClass("selected"); $thumbs.eq(this.currentImage.index).addClass("selected"); return this }, updateThumbs: function (postTransitionOutHandler) { var gallery = this; var transitionOutCallback = function () { if (postTransitionOutHandler) { postTransitionOutHandler() } gallery.rebuildThumbs(); if (gallery.onPageTransitionIn) { gallery.onPageTransitionIn() } else { gallery.show() } }; if (this.onPageTransitionOut) { this.onPageTransitionOut(transitionOutCallback) } else { this.hide(); transitionOutCallback() } return this }, rebuildThumbs: function () { var needsPagination = this.data.length > this.numThumbs; 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) } } 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 } 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; $thumbsUl.removeClass("noscript"); return this }, getNumPages: function () { return Math.ceil(this.data.length / this.numThumbs) }, 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 } if (page > 0) { var prevPage = startIndex - this.numThumbs; pager.append('<a rel="history" href="#' + this.data[prevPage].hash + '" title="' + this.prevPageLinkText + '">' + this.prevPageLinkText + "</a>") } if (pageNum > 0) { this.buildPageLink(pager, 0, numPages); if (pageNum > 1) { pager.append('<span class="ellipsis">&hellip;</span>') } pagesRemaining-- } while (pagesRemaining > 0) { this.buildPageLink(pager, pageNum, numPages); pagesRemaining--; pageNum++ } if (pageNum < numPages) { var lastPageNum = numPages - 1; if (pageNum < lastPageNum) { pager.append('<span class="ellipsis">&hellip;</span>') } this.buildPageLink(pager, lastPageNum, numPages) } 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 }, 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 } }); $.extend(this, defaults, settings); if (this.enableHistory && !$.historyInit) { this.enableHistory = false } if (this.imageContainerSel) { this.$imageContainer = $(this.imageContainerSel) } if (this.captionContainerSel) { this.$captionContainer = $(this.captionContainerSel) } if (this.loadingContainerSel) { this.$loadingContainer = $(this.loadingContainerSel) } this.initializeThumbs(); if (this.maxPagesToShow < 3) { this.maxPagesToShow = 3 } this.displayedPage = -1; this.currentImage = this.data[0]; var gallery = this; if (this.$loadingContainer) { this.$loadingContainer.hide() } if (this.controlsContainerSel) { this.$controlsContainer = $(this.controlsContainerSel).empty(); if (this.renderSSControls) { if (this.autoStart) { this.$controlsContainer.append('<div class="ss-controls"><a href="#pause" class="pause" title="' + this.pauseLinkText + '">' + this.pauseLinkText + "</a></div>") } else { this.$controlsContainer.append('<div class="ss-controls"><a href="#play" class="play" title="' + this.playLinkText + '">' + this.playLinkText + "</a></div>") } this.$controlsContainer.find("div.ss-controls a").click(function (e) { gallery.toggleSlideshow(); e.preventDefault(); return false }) } if (this.renderNavControls) { this.$controlsContainer.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 } } if (initFirstImage) { this.gotoIndex(0, false, true) } if (this.enableKeyboardNavigation) { $(document).keydown(function (e) { var key = e.charCode ? e.charCode : e.keyCode ? e.keyCode : 0; switch (key) { case 32: gallery.next(); e.preventDefault(); break; case 33: gallery.previousPage(); e.preventDefault(); break; case 34: gallery.nextPage(); e.preventDefault(); break; case 35: gallery.gotoIndex(gallery.data.length - 1); e.preventDefault(); break; case 36: gallery.gotoIndex(0); e.preventDefault(); break; case 37: gallery.previous(); e.preventDefault(); break; case 39: gallery.next(); e.preventDefault(); break } }) } if (this.autoStart) { this.play() } setTimeout(function () { gallery.preloadInit() }, 1000); return this } })(jQuery);
