File: assets/js/jquery.popeye-2.1.js

Recommend this page to a friend!
  Classes of Michael Beck  >  XOOPS Publisher Module  >  assets/js/jquery.popeye-2.1.js  >  Download  
File: assets/js/jquery.popeye-2.1.js
Role: Auxiliary data
Content type: text/plain
Description: Auxiliary data
Class: XOOPS Publisher Module
Publish static HTML content and article with XOOPS
Author: By
Last change:
Date: 1 year ago
Size: 28,080 bytes
 

 

Contents

Class file image Download
/*
 * jQuery Popeye 2.1 - http://dev.herr-schuessler.de/jquery/popeye/
 *
 * converts a HTML image list in image gallery with inline enlargement
 *
 * Copyright (C) 2008 - 2011 Christoph Schuessler (schreib@herr-schuessler.de)
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 */

(function ($) {


    ////////////////////////////////////////////////////////////////////////////
    //
    // $.fn.popeye
    // popeye definition
    //
    ////////////////////////////////////////////////////////////////////////////
    $.fn.popeye = function (options) {
        'use strict';

        // build main options before element iteration
        //----------------------------------------------------------------------
        var opts = $.extend({}, $.fn.popeye.defaults, options);

        ////////////////////////////////////////////////////////////////////////////////
        //
        // firebug console output
        // @param text String the debug message
        // @param type String the message type [info | warn] (optional)
        //
        ////////////////////////////////////////////////////////////////////////////////
        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);
                }
            }
        }

        // let's go!
        //----------------------------------------------------------------------
        return this.each(function () {

            // first thing to do: make ppy html visible
            $(this).addClass('ppy-active');

            // cache object
            var $self = $(this),

                // images
                img = $self.find('.ppy-imglist > li > a > img'),
                a = $self.find('.ppy-imglist > li > a'),
                tot = img.length,

                // single image mode
                singleImageMode = (tot === 1),

                // flag for moueover check
                ismouseover = false,

                // start in compact mode
                enlarged = false,

                // counter vars
                cur = 0,                // array index of currently displayed image

                // extra classes
                eclass = 'ppy-expanded',       //class to be applied to enlarged popeye-box
                lclass = 'ppy-loading',        //class to be applied to stage while loading image
                sclass = 'ppy-single-image',   //class to be applied to popeye-box if there's only one image to display

                // html nodes
                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'),
                ppyPlay = $self.find('.ppy-play'),
                ppyPause = $self.find('.ppy-pause').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'),

                // css objects
                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'),
                    'margin-top': $self.css('margin-top'),
                    'margin-right': $self.css('margin-right'),
                    'margin-bottom': $self.css('margin-bottom'),
                    'margin-left': $self.css('margin-left')
                };

            // make caption array from caption element or alt tag
            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;
            }

            // check for html errors
            if (!ppyStage.length || !ppyNav.length || !ppyOuter.length) {
                debug('$.fn.popeye: Incorrect HTML structure', 'warn');
            }

            // check for images
            else if (tot === 0) {
                debug('$.fn.popeye: No images found', 'warn');
            }
            // no errors, setup done!
            //------------------------------------------------------------------
            else {
                singleImageMode ? debug('$.fn.popeye -> SingleImageMode started') : debug('$.fn.popeye -> ' + tot + ' thumbnails found.');
                init();
            }

            ////////////////////////////////////////////////////////////////////
            //
            // $.fn.popeye.showThumb
            // show thumbnail
            // @param i Int the index of the thumbnail to show (optional)
            // @param transition Bool show transition between images (optional)
            //
            ////////////////////////////////////////////////////////////////////
            function showThumb(i, transition) {

                // optional parameters
                transition = transition || false;
                i = i || cur;

                // set selected thumb as background image of stage
                var cssStageImage = {
                    backgroundImage: 'url(' + img[i].src + ')'
                };
                // bogus animation css for IE
                var cssTemp = {
                    height: '+=0'
                };

                // if we are in enlarged mode, return to thumb mode
                if (enlarged) {

                    hideCaption();

                    // fade image out and compact stage with transition
                    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');

                            // remove extra styling and reset z-index
                            $self.removeClass(eclass);
                            $self.css('z-index', '').parent().css('z-index', '');

                            // switch buttons
                            ppySwitchEnlarge.removeClass('ppy-hidden');
                            ppySwitchCompact.addClass('ppy-hidden');

                            // recursive function call
                            showThumb();

                            // fade the stage back in
                            $(this).fadeTo((opts.duration / 2), 1);
                        }
                    });
                }
                else {

                    // if we navigate from one image to the next, fade out the stage
                    if (transition) {

                        // fade out image so that background shines through
                        // background can contain loading gfx
                        ppyStageWrap.addClass(lclass);
                        ppyStage.fadeTo((opts.duration / 2), 0);

                        // once thumb has loadded...
                        var thumbPreloader = new Image();
                        thumbPreloader.onload = function () {
                            debug('$.fn.popeye.showThumb: Thumbnail ' + i + ' loaded', 'info');

                            // remove loading indicator
                            ppyStageWrap.removeClass(lclass);

                            // add all upcoming animations to the queue so that
                            // they won't start when the preolader has loaded but when the fadeOut has finished
                            ppyStage.animate(cssTemp, 1, 'linear', function () {

                                // set the new image
                                ppyStage.css(cssStageImage);
                                // fade the stage back in
                                $(this).fadeTo((opts.duration / 2), 1);

                                // update counter and caption
                                if (opts.caption === 'hover' && ismouseover) {
                                    showCaption(cap[i]);
                                }
                                else if (opts.caption === 'permanent') {
                                    updateCaption(cap[i]);
                                }
                                updateCounter();
                            });

                            //  fix IE animated gif bug
                            thumbPreloader.onload = function () {
                            };
                        };
                        // preload thumb
                        thumbPreloader.src = img[i].src;
                    }

                    // or just drag the image to the stage
                    else {
                        ppyStage.css(cssStageImage);
                        updateCounter();

                        //if(ismouseover) {
                        showCaption(cap[i], true);
                        //}
                    }

                    // preload big image for instant availability
                    var preloader = new Image();

                    preloader.onload = function () {
                        debug('$.fn.popeye.showThumb: Image ' + i + ' loaded', 'info');
                        preloader.onload = function () {
                        };
                    };

                    preloader.src = a[i].href;
                }
            }


            ////////////////////////////////////////////////////////////////////
            //
            // $.fn.popeye.showImage
            // show large image
            // @param i Int the index of the image to show (optional)
            //
            ////////////////////////////////////////////////////////////////////
            function showImage(i) {

                // optional parameter i
                i = i || cur;

                // fade out image so that background shines through
                // background can contain loading gfx
                ppyStageWrap.addClass(lclass);
                ppyStage.fadeTo((opts.duration / 2), 0);

                // if there are multiple popeyes opened at the same time,
                // make sure the current one gets a higher z-index
                var allPpy = $('.' + eclass);
                allPpy.css('z-index', opts.zindex - 1);

                //both ppy and placeholder (for IE7) need high z-index
                $self.css('z-index', opts.zindex).parent().css('z-index', opts.zindex);

                // once image has loadded...
                var preloader = new Image();
                preloader.onload = function () {

                    // remove loading class
                    ppyStageWrap.removeClass(lclass);

                    // set css
                    var cssStageTo = {
                        width: preloader.width,
                        height: preloader.height
                    };
                    var cssStageIm = {
                        backgroundImage: 'url(' + a[i].href + ')',
                        backgroundPosition: 'left top'
                    };

                    hideCaption();

                    // show transitional animation
                    ppyStage.animate(cssStageTo, {
                        queue: false,
                        duration: opts.duration,
                        easing: opts.easing,
                        complete: function () {

                            if (opts.navigation === 'hover' && ismouseover) {
                                showNav();
                            }

                            enlarged = true;
                            debug('$.fn.popeye.showImage: Entering ENLARGED MODE', 'info');

                            // add extra class, expanded box can be styled accordingly
                            $self.addClass(eclass);

                            // switch buttons
                            ppySwitchCompact.removeClass('ppy-hidden');
                            ppySwitchEnlarge.addClass('ppy-hidden');

                            updateCounter();

                            // set new bg image and fade it in
                            $(this).css(cssStageIm).fadeTo((opts.duration / 2), 1);

                            // show caption
                            showCaption(cap[i]);

                            preloadNeighbours();
                        }
                    });
                };

                // preload image
                preloader.src = a[i].href;

            }


            ////////////////////////////////////////////////////////////////////
            //
            // $.fn.popeye.updateCounter
            // update image counter
            // @param i Int the index of the image (optional)
            //
            ////////////////////////////////////////////////////////////////////
            function updateCounter(i) {

                // optional parameter
                i = i || cur;

                ppyTotal.text(tot);        // total images
                ppyCurrent.text(i + 1);    // current image number
                debug('$.fn.popeye.updateCounter: Displaying image ' + (i + 1) + ' of ' + tot);
            }

            ////////////////////////////////////////////////////////////////////
            //
            // $.fn.popeye.preloadNeighbours
            // preload next and previos image
            // @param i Int the index of the current image (optional)
            //
            ////////////////////////////////////////////////////////////////////
            function preloadNeighbours(i) {

                // optional parameter
                i = i || cur;

                var preloaderNext = new Image();
                var preloaderPrev = new Image();

                var neighbour = i;

                // next image
                if (neighbour < ( tot - 1)) {
                    neighbour++;
                } else {
                    neighbour = 0;
                }
                preloaderNext.src = a[neighbour].href;

                // previous image
                neighbour = i;
                if (neighbour <= 0) {
                    neighbour = tot - 1;
                } else {
                    neighbour--;
                }
                preloaderPrev.src = a[neighbour].href;
            }


            ////////////////////////////////////////////////////////////////////
            //
            // $.fn.popeye.showNav
            //
            ////////////////////////////////////////////////////////////////////
            function showNav() {
                ppyNav.stop().fadeTo(150, opts.opacity);
            }


            ////////////////////////////////////////////////////////////////////
            //
            // $.fn.popeye.hideNav
            //
            ////////////////////////////////////////////////////////////////////
            function hideNav() {
                ppyNav.stop().fadeTo(150, 0);
            }


            ////////////////////////////////////////////////////////////////////
            //
            // $.fn.popeye.updateCaption
            // @param caption String the caption string
            //
            ////////////////////////////////////////////////////////////////////
            function updateCaption(caption) {

                if (opts.caption) {
                    // update text box
                    ppyText.html(caption);
                }
            }

            ////////////////////////////////////////////////////////////////////
            //
            // $.fn.popeye.showCaption
            // @param caption String the caption string
            // @param force Boolean force caption display even if caption string is empty
            //
            ////////////////////////////////////////////////////////////////////
            function showCaption(caption, force) {

                // if caption string is not empty...
                if (caption && opts.caption) {
                    updateCaption(caption);

                    debug('$.fn.popeye.showCaption -> ppyCaptionWrap.outerHeight(true): ' + ppyCaptionWrap.outerHeight(true));

                    // make caption box visible
                    var cssTempCaption = {
                        visibility: 'visible'
                    };
                    ppyCaption.css(cssTempCaption);

                    if (opts.caption === 'permanent' && !enlarged) {

                        // return to original caption height
                        ppyCaption.css(cssCaption);
                    }
                    else {

                        // or animate it to its childs height
                        ppyCaption.animate({'height': ppyCaptionWrap.outerHeight(true)}, {
                            queue: false,
                            duration: 90,
                            easing: opts.easing
                        });
                    }
                }
                // if there's no caption to show...
                else if (!caption && !force) {
                    hideCaption();
                }
            }


            ////////////////////////////////////////////////////////////////////
            //
            // $.fn.popeye.hideCaption
            //
            ////////////////////////////////////////////////////////////////////
            function hideCaption() {

                // css to hide caption but allow its inner text box to expand to content height
                var cssTempCaption = {
                    visibility: 'hidden',
                    overflow: 'hidden'
                };

                // slide up caption box and hide it when done
                ppyCaption.animate({'height': '0px'}, {
                    queue: false,
                    duration: 90,
                    easing: opts.easing,
                    complete: function () {
                        ppyCaption.css(cssTempCaption);
                    }
                });
            }

            ////////////////////////////////////////////////////////////////////
            //
            // $.fn.popeye.previous
            // show previous image
            //
            ////////////////////////////////////////////////////////////////////
            function previous() {
                if (cur <= 0) {
                    cur = tot - 1;
                } else {
                    cur--;
                }
                if (enlarged) {
                    showImage(cur);
                }
                else {
                    showThumb(cur, true);
                }
                return cur;
            }

            ////////////////////////////////////////////////////////////////////
            //
            // $.fn.popeye.next
            // show next image
            //
            ////////////////////////////////////////////////////////////////////
            function next() {
                if (cur < ( tot - 1)) {
                    cur++;
                } else {
                    cur = 0;
                }
                if (enlarged) {
                    showImage(cur);
                }
                else {
                    showThumb(cur, true);
                }
                return cur;
            }

            ////////////////////////////////////////////////////////////////////
            //
            // $.fn.popeye.init
            // setup of popeye DOM and events
            //
            ////////////////////////////////////////////////////////////////////
            function init() {

                // popeye dom setup
                //--------------------------------------------------------------

                // add css
                ppyPlaceholder.css(cssPlaceholder);
                $self.css(cssSelf);

                // wrap popeye in placeholder
                $self.wrap(ppyPlaceholder);

                // wrap stage in container for extra styling (e.g. loading gfx)
                ppyStageWrap = ppyStage.wrap(ppyStageWrap).parent();

                // wrap caption contents in wrapper (can't use wrap() here...)
                ppyCaptionWrap = ppyCaption.wrapInner(ppyCaptionWrap).children().eq(0);

                // display first image
                showThumb();

                // add event handlers
                //--------------------------------------------------------------
                // hover behaviour for navigation
                if (opts.navigation == 'hover') {
                    hideNav();
                    $self.hover(
                        function () {
                            showNav();
                        },
                        function () {
                            hideNav();
                        }
                    );
                    ppyNav.hover(
                        function () {
                            showNav();
                        },
                        function () {
                            hideNav();
                        }
                    );
                }
                if (!singleImageMode) {

                    // previous image button
                    ppyPrev.click(function (e) {
                        e.stopPropagation();
                        previous();
                    });

                    // next image button
                    ppyNext.click(function (e) {
                        e.stopPropagation();
                        next();
                    });

                }
                else {
                    $self.addClass(sclass);
                    ppyPrev.remove();
                    ppyNext.remove();
                    ppyPlay.remove();
                    ppyPause.remove();
                    ppyCounter.remove();
                }

                // hover behaviour for caption
                if (opts.caption === 'hover') {
                    hideCaption();
                    $self.hover(
                        function () {
                            showCaption(cap[cur]);
                        },
                        function () {
                            hideCaption(true);
                        }
                    );
                }

                // enlarge image button
                ppySwitchEnlarge.click(function (e) {
                    e.stopPropagation();
                    showImage();
                    return false;
                });

                // compact image button
                ppySwitchCompact.click(function (e) {
                    e.stopPropagation();
                    showThumb(cur);
                    return false;
                });

                ppyStage.click(function () {
                    if (enlarged) {
                        showThumb(cur);
                    }
                    else {
                        showImage();
                    }

                });

                //play button
                ppyPlay.click(function (e) {
                    e.stopPropagation();

                    // switch buttons
                    ppyPause.removeClass('ppy-hidden');
                    ppyPlay.addClass('ppy-hidden');

                    // initiate Slideshow
                    var slideshow;
                    slideshow = window.setInterval(function () {
                        next();
                    }, opts.slidespeed);
                    return false;
                });

                //pause button
                ppyPause.click(function (e) {
                    e.stopPropagation();

                    // switch buttons
                    ppyPlay.removeClass('ppy-hidden');
                    ppyPause.addClass('ppy-hidden');

                    // stop Slideshow
                    window.clearInterval(slideshow);
                    return false;
                });

                // mouseover flag
                $self.mouseenter(function () {
                    ismouseover = true;
                }).mouseleave(function () {
                    ismouseover = false;
                });

                // start autoslide
                if (opts.autoslide) {
                    ppyPlay.trigger('click');
                }

            }
        });
    };

    ////////////////////////////////////////////////////////////////////////////
    //
    // $.fn.popeye.defaults
    // set default  options
    //
    ////////////////////////////////////////////////////////////////////////////
    $.fn.popeye.defaults = {

        navigation: 'hover',            //visibility of navigation - can be 'permanent' or 'hover'
        caption: 'hover',            //visibility of caption, based on image title - can be false, 'permanent' or 'hover'

        zindex: 10000,              //z-index of the expanded popeye-box. enter a z-index that works well with your site and doesn't overlay your site's navigational elements like dropdowns

        direction: 'right',            //direction that popeye-box opens, can be 'left' or 'right'
        duration: 240,                //duration of transitional effect when enlarging or closing the box
        opacity: 0.8,                //opacity of navigational overlay (only applicable if 'navigation' is set to 'hover'
        easing: 'swing',            //easing type, can be 'swing', 'linear' or any of jQuery Easing Plugin types (Plugin required)

        slidespeed: 2000,               //timespan that one image is shown in a slideshow
        autoslide: false,              //should the slideshow start automatically?

        debug: false

    };

// end of closure, bind to jQuery Object
})(jQuery);


////////////////////////////////////////////////////////////////////////////////
//
// avoid content flicker for non-js user agents
// (in order to use this, the js-files have to be included in the head of the
// html file!)
//
////////////////////////////////////////////////////////////////////////////////
jQuery('head').append('<style type="text/css"> .ppy-imglist { position: absolute; top: -1000em; left: -1000em; } </style>');

For more information send a message to info at phpclasses dot org.