(function($) { $.fn.popeye = function(options) { var opts = $.extend({}, $.fn.popeye.defaults, options); function debug(text, type) { if (window.console && window.console.log && opts.debug) { if (type == 'info' && window.console.info) { window.console.info(text) } else if (type == 'warn' && window.console.warn) { window.console.warn(text) } else { window.console.log(text) } } } return this.each(function() { $(this).addClass('ppy-active'); var $self = $(this), img = $self.find('.ppy-imglist > li > a > img'), a = $self.find('.ppy-imglist > li > a'), tot = img.length, singleImageMode = (tot == 1) ? true : false, enlarged = false, cur = 0, eclass = 'ppy-expanded', lclass = 'ppy-loading', sclass = 'ppy-single-image', ppyPlaceholder = $('<div class="ppy-placeholder"></div>'), ppyStageWrap = $('<div class="ppy-stagewrap"></div>'), ppyCaptionWrap = $('<div class="ppy-captionwrap"></div>'), ppyOuter = $self.find('.ppy-outer'), ppyStage = $self.find('.ppy-stage'), ppyNav = $self.find('.ppy-nav'), ppyPrev = $self.find('.ppy-prev'), ppyNext = $self.find('.ppy-next'), ppySwitchEnlarge = $self.find('.ppy-switch-enlarge'), ppySwitchCompact = $self.find('.ppy-switch-compact').addClass('ppy-hidden'), ppyCaption = $self.find('.ppy-caption'), ppyText = $self.find('.ppy-text'), ppyCounter = $self.find('.ppy-counter'), ppyCurrent = $self.find('.ppy-current'), ppyTotal = $self.find('.ppy-total'), cssSelf = { position: 'absolute', width: 'auto', height: 'auto', margin: 0, top: 0, left: (opts.direction == 'right') ? 0 : 'auto', right: (opts.direction == 'left') ? 0 : 'auto' }, cssStage = { height: ppyStage.height(), width: ppyStage.width() }, cssCaption = { height: ppyCaption.height() }, cssPlaceholder = { height: (opts.caption == 'hover' || false) ? ppyOuter.outerHeight() : $self.outerHeight(), width: (opts.caption == 'hover' || false) ? ppyOuter.outerWidth() : $self.outerWidth(), float: $self.css('float'), marginTop: $self.css('margin-top'), marginRight: $self.css('margin-right'), marginBottom: $self.css('margin-bottom'), marginLeft: $self.css('margin-left') }; var cap = []; for (var i = 0; i < img.length; i++) { var extcap = $self.find('.ppy-imglist li').eq(i).find('.ppy-extcaption'); cap[i] = extcap.length > 0 ? extcap.html() : img[i].alt } if (!ppyStage.length || !ppyNav.length || !ppyOuter.length) { debug('$.fn.popeye: Incorrect HTML structure', 'warn') } else if (tot === 0) { debug('$.fn.popeye: No images found', 'warn') } else { singleImageMode ? debug('$.fn.popeye -> SingleImageMode started') : debug('$.fn.popeye -> ' + tot + ' thumbnails found.'); init() } function showThumb(i, transition) { transition = transition || false; i = i || cur; var cssStageImage = { backgroundImage: 'url(' + img[i].src + ')' }; var cssTemp = { height: '+=0' }; if (enlarged) { hideCaption(); ppyStage.fadeTo((opts.duration / 2), 0).animate(cssStage, { queue: false, duration: opts.duration, easing: opts.easing, complete: function() { enlarged = false; debug('$.fn.showThumb: Entering COMPACT MODE', 'info'); $self.removeClass(eclass); $self.css('z-index', ''); ppySwitchEnlarge.removeClass('ppy-hidden'); ppySwitchCompact.addClass('ppy-hidden'); showThumb(); $(this).fadeTo((opts.duration / 2), 1) } }) } else { if (transition) { ppyStageWrap.addClass(lclass); ppyStage.fadeTo((opts.duration / 2), 0); var thumbPreloader = new Image(); thumbPreloader.onload = function() { debug('$.fn.popeye.showThumb: Thumbnail ' + i + ' loaded', 'info'); ppyStageWrap.removeClass(lclass); ppyStage.animate(cssTemp, 1, 'linear', function() { ppyStage.css(cssStageImage); $(this).fadeTo((opts.duration / 2), 1); if (opts.caption == 'hover') { showCaption(cap[i]) } else if (opts.caption == 'permanent') { updateCaption(cap[i]) } updateCounter() }); thumbPreloader.onload = function() { } }; thumbPreloader.src = img[i].src } else { ppyStage.css(cssStageImage); updateCounter(); showCaption(cap[i], true) } var preloader = new Image(); preloader.onload = function() { debug('$.fn.popeye.showThumb: Image ' + i + ' loaded', 'info'); preloader.onload = function() { } }; preloader.src = a[i].href } } function showImage(i) { i = i || cur; ppyStageWrap.addClass(lclass); ppyStage.fadeTo((opts.duration / 2), 0); var allPpy = $('.' + eclass); allPpy.css('z-index', opts.zindex - 1); $self.css('z-index', opts.zindex); var preloader = new Image(); preloader.onload = function() { ppyStageWrap.removeClass(lclass); var cssStageTo = { width: preloader.width, height: preloader.height }; var cssStageIm = { backgroundImage: 'url(' + a[i].href + ')', backgroundPosition: 'left top' }; hideCaption(); ppyStage.animate(cssStageTo, { queue: false, duration: opts.duration, easing: opts.easing, complete: function() { if (opts.navigation == 'hover') { showNav() } enlarged = true; debug('$.fn.popeye.showImage: Entering ENLARGED MODE', 'info'); $self.addClass(eclass); ppySwitchCompact.removeClass('ppy-hidden'); ppySwitchEnlarge.addClass('ppy-hidden'); updateCounter(); $(this).css(cssStageIm).fadeTo((opts.duration / 2), 1); showCaption(cap[i]); preloadNeighbours() } }) }; preloader.src = a[i].href } function updateCounter(i) { i = i || cur; ppyTotal.text(tot); ppyCurrent.text(i + 1); debug('$.fn.popeye.updateCounter: Displaying image ' + (i + 1) + ' of ' + tot) } function preloadNeighbours(i) { i = i || cur; var preloaderNext = new Image(); var preloaderPrev = new Image(); var neighbour = i; if (neighbour < (tot - 1)) { neighbour++ } else { neighbour = 0 } preloaderNext.src = a[i].href[neighbour]; neighbour = i; if (neighbour <= 0) { neighbour = tot - 1 } else { neighbour-- } preloaderPrev.src = a[i].href[neighbour] } function showNav() { ppyNav.stop().fadeTo(150, opts.opacity) } function hideNav() { ppyNav.stop().fadeTo(150, 0) } function updateCaption(caption) { if (opts.caption) { ppyText.html(caption) } } function showCaption(caption, force) { if (caption && opts.caption) { updateCaption(caption); debug('$.fn.popeye.showCaption -> ppyCaptionWrap.outerHeight(true): ' + ppyCaptionWrap.outerHeight(true)); var cssTempCaption = { visibility: 'visible' }; ppyCaption.css(cssTempCaption); if (opts.caption === 'permanent' && !enlarged) { ppyCaption.css(cssCaption) } else { ppyCaption.animate({ 'height': ppyCaptionWrap.outerHeight(true) }, { queue: false, duration: 90, easing: opts.easing }) } } else if (!caption && !force) { hideCaption() } } function hideCaption() { var cssTempCaption = { visibility: 'hidden', overflow: 'hidden' }; ppyCaption.animate({ 'height': '0px' }, { queue: false, duration: 90, easing: opts.easing, complete: function() { ppyCaption.css(cssTempCaption) } }) } function previous() { if (cur <= 0) { cur = tot - 1 } else { cur-- } if (enlarged) { showImage(cur) } else { showThumb(cur, true) } return cur } function next() { if (cur < (tot - 1)) { cur++ } else { cur = 0 } if (enlarged) { showImage(cur) } else { showThumb(cur, true) } return cur } function init() { ppyPlaceholder.css(cssPlaceholder); $self.css(cssSelf); $self.wrap(ppyPlaceholder); ppyStageWrap = ppyStage.wrap(ppyStageWrap).parent(); ppyCaptionWrap = ppyCaption.wrapInner(ppyCaptionWrap).children().eq(0); showThumb(); if (opts.navigation == 'hover') { hideNav(); $self.hover(function() { showNav() }, function() { hideNav() }); ppyNav.hover(function() { showNav() }, function() { hideNav() }) } if (!singleImageMode) { ppyPrev.click(previous); ppyNext.click(next) } else { $self.addClass(sclass); ppyPrev.remove(); ppyNext.remove(); ppyCounter.remove(); ppyNav.remove() } if (opts.caption == 'hover') { hideCaption(); $self.hover(function() { showCaption(cap[cur]) }, function() { hideCaption(true) }) } ppySwitchEnlarge.click(function() { showImage(); return false }); ppySwitchCompact.click(function() { showThumb(cur); return false }) } }) }; $.fn.popeye.defaults = { navigation: 'hover', caption: 'hover', zindex: 10000, direction: 'right', duration: 240, opacity: 0.8, easing: 'swing', debug: false} })(jQuery); jQuery('head').append('<style type="text/css"> .ppy-imglist { position: absolute; top: -1000em; left: -1000em; } </style>');
