码迷,mamicode.com
首页 > Web开发 > 详细

js实现左右点击图片层叠滚动特效

时间:2015-11-11 19:06:44      阅读:255      评论:0      收藏:0      [点我收藏+]

标签:

技术分享

需要加载js有

<script type="text/javascript" src="js/jquery-1.7.2.min.js"></script>
<script type="text/javascript" src="js/jquery.corner.js"></script>
<script type="text/javascript" src="js/jquery.roundabout.js"></script>
<script type="text/javascript" src="js/jquery.roundabout-shapes.js"></script>

技术分享
/*!
 * jQuery corner plugin: simple corner rounding
 * Examples and documentation at: http://jquery.malsup.com/corner/
 * version 2.12 (23-MAY-2011)
 * Requires jQuery v1.3.2 or later
 * Dual licensed under the MIT and GPL licenses:
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl.html
 * Authors: Dave Methvin and Mike Alsup
 */

/**
 *  corner() takes a single string argument:  $(‘#myDiv‘).corner("effect corners width")
 *
 *  effect:  name of the effect to apply, such as round, bevel, notch, bite, etc (default is round). 
 *  corners: one or more of: top, bottom, tr, tl, br, or bl.  (default is all corners)
 *  width:   width of the effect; in the case of rounded corners this is the radius. 
 *           specify this value using the px suffix such as 10px (yes, it must be pixels).
 */
;(function($) { 

var style = document.createElement(‘div‘).style,
    moz = style[‘MozBorderRadius‘] !== undefined,
    webkit = style[‘WebkitBorderRadius‘] !== undefined,
    radius = style[‘borderRadius‘] !== undefined || style[‘BorderRadius‘] !== undefined,
    mode = document.documentMode || 0,
    noBottomFold = $.browser.msie && (($.browser.version < 8 && !mode) || mode < 8),

    expr = $.browser.msie && (function() {
        var div = document.createElement(‘div‘);
        try { div.style.setExpression(‘width‘,‘0+0‘); div.style.removeExpression(‘width‘); }
        catch(e) { return false; }
        return true;
    })();

$.support = $.support || {};
$.support.borderRadius = moz || webkit || radius; // so you can do:  if (!$.support.borderRadius) $(‘#myDiv‘).corner();

function sz(el, p) { 
    return parseInt($.css(el,p))||0; 
};
function hex2(s) {
    s = parseInt(s).toString(16);
    return ( s.length < 2 ) ? ‘0‘+s : s;
};
function gpc(node) {
    while(node) {
        var v = $.css(node,‘backgroundColor‘), rgb;
        if (v && v != ‘transparent‘ && v != ‘rgba(0, 0, 0, 0)‘) {
            if (v.indexOf(‘rgb‘) >= 0) { 
                rgb = v.match(/\d+/g); 
                return ‘#‘+ hex2(rgb[0]) + hex2(rgb[1]) + hex2(rgb[2]);
            }
            return v;
        }
        if (node.nodeName.toLowerCase() == ‘html‘)
            break;
        node = node.parentNode; // keep walking if transparent
    }
    return ‘#ffffff‘;
};

function getWidth(fx, i, width) {
    switch(fx) {
    case ‘round‘:  return Math.round(width*(1-Math.cos(Math.asin(i/width))));
    case ‘cool‘:   return Math.round(width*(1+Math.cos(Math.asin(i/width))));
    case ‘sharp‘:  return width-i;
    case ‘bite‘:   return Math.round(width*(Math.cos(Math.asin((width-i-1)/width))));
    case ‘slide‘:  return Math.round(width*(Math.atan2(i,width/i)));
    case ‘jut‘:    return Math.round(width*(Math.atan2(width,(width-i-1))));
    case ‘curl‘:   return Math.round(width*(Math.atan(i)));
    case ‘tear‘:   return Math.round(width*(Math.cos(i)));
    case ‘wicked‘: return Math.round(width*(Math.tan(i)));
    case ‘long‘:   return Math.round(width*(Math.sqrt(i)));
    case ‘sculpt‘: return Math.round(width*(Math.log((width-i-1),width)));
    case ‘dogfold‘:
    case ‘dog‘:    return (i&1) ? (i+1) : width;
    case ‘dog2‘:   return (i&2) ? (i+1) : width;
    case ‘dog3‘:   return (i&3) ? (i+1) : width;
    case ‘fray‘:   return (i%2)*width;
    case ‘notch‘:  return width; 
    case ‘bevelfold‘:
    case ‘bevel‘:  return i+1;
    case ‘steep‘:  return i/2 + 1;
    case ‘invsteep‘:return (width-i)/2+1;
    }
};

$.fn.corner = function(options) {
    // in 1.3+ we can fix mistakes with the ready state
    if (this.length == 0) {
        if (!$.isReady && this.selector) {
            var s = this.selector, c = this.context;
            $(function() {
                $(s,c).corner(options);
            });
        }
        return this;
    }

    return this.each(function(index){
        var $this = $(this),
            // meta values override options
            o = [$this.attr($.fn.corner.defaults.metaAttr) || ‘‘, options || ‘‘].join(‘ ‘).toLowerCase(),
            keep = /keep/.test(o),                       // keep borders?
            cc = ((o.match(/cc:(#[0-9a-f]+)/)||[])[1]),  // corner color
            sc = ((o.match(/sc:(#[0-9a-f]+)/)||[])[1]),  // strip color
            width = parseInt((o.match(/(\d+)px/)||[])[1]) || 10, // corner width
            re = /round|bevelfold|bevel|notch|bite|cool|sharp|slide|jut|curl|tear|fray|wicked|sculpt|long|dog3|dog2|dogfold|dog|invsteep|steep/,
            fx = ((o.match(re)||[‘round‘])[0]),
            fold = /dogfold|bevelfold/.test(o),
            edges = { T:0, B:1 },
            opts = {
                TL:  /top|tl|left/.test(o),       TR:  /top|tr|right/.test(o),
                BL:  /bottom|bl|left/.test(o),    BR:  /bottom|br|right/.test(o)
            },
            // vars used in func later
            strip, pad, cssHeight, j, bot, d, ds, bw, i, w, e, c, common, $horz;
        
        if ( !opts.TL && !opts.TR && !opts.BL && !opts.BR )
            opts = { TL:1, TR:1, BL:1, BR:1 };
            
        // support native rounding
        if ($.fn.corner.defaults.useNative && fx == ‘round‘ && (radius || moz || webkit) && !cc && !sc) {
            if (opts.TL)
                $this.css(radius ? ‘border-top-left-radius‘ : moz ? ‘-moz-border-radius-topleft‘ : ‘-webkit-border-top-left-radius‘, width + ‘px‘);
            if (opts.TR)
                $this.css(radius ? ‘border-top-right-radius‘ : moz ? ‘-moz-border-radius-topright‘ : ‘-webkit-border-top-right-radius‘, width + ‘px‘);
            if (opts.BL)
                $this.css(radius ? ‘border-bottom-left-radius‘ : moz ? ‘-moz-border-radius-bottomleft‘ : ‘-webkit-border-bottom-left-radius‘, width + ‘px‘);
            if (opts.BR)
                $this.css(radius ? ‘border-bottom-right-radius‘ : moz ? ‘-moz-border-radius-bottomright‘ : ‘-webkit-border-bottom-right-radius‘, width + ‘px‘);
            return;
        }
            
        strip = document.createElement(‘div‘);
        $(strip).css({
            overflow: ‘hidden‘,
            height: ‘1px‘,
            minHeight: ‘1px‘,
            fontSize: ‘1px‘,
            backgroundColor: sc || ‘transparent‘,
            borderStyle: ‘solid‘
        });
    
        pad = {
            T: parseInt($.css(this,‘paddingTop‘))||0,     R: parseInt($.css(this,‘paddingRight‘))||0,
            B: parseInt($.css(this,‘paddingBottom‘))||0,  L: parseInt($.css(this,‘paddingLeft‘))||0
        };

        if (typeof this.style.zoom != undefined) this.style.zoom = 1; // force ‘hasLayout‘ in IE
        if (!keep) this.style.border = ‘none‘;
        strip.style.borderColor = cc || gpc(this.parentNode);
        cssHeight = $(this).outerHeight();

        for (j in edges) {
            bot = edges[j];
            // only add stips if needed
            if ((bot && (opts.BL || opts.BR)) || (!bot && (opts.TL || opts.TR))) {
                strip.style.borderStyle = ‘none ‘+(opts[j+‘R‘]?‘solid‘:‘none‘)+‘ none ‘+(opts[j+‘L‘]?‘solid‘:‘none‘);
                d = document.createElement(‘div‘);
                $(d).addClass(‘jquery-corner‘);
                ds = d.style;

                bot ? this.appendChild(d) : this.insertBefore(d, this.firstChild);

                if (bot && cssHeight != ‘auto‘) {
                    if ($.css(this,‘position‘) == ‘static‘)
                        this.style.position = ‘relative‘;
                    ds.position = ‘absolute‘;
                    ds.bottom = ds.left = ds.padding = ds.margin = ‘0‘;
                    if (expr)
                        ds.setExpression(‘width‘, ‘this.parentNode.offsetWidth‘);
                    else
                        ds.width = ‘100%‘;
                }
                else if (!bot && $.browser.msie) {
                    if ($.css(this,‘position‘) == ‘static‘)
                        this.style.position = ‘relative‘;
                    ds.position = ‘absolute‘;
                    ds.top = ds.left = ds.right = ds.padding = ds.margin = ‘0‘;
                    
                    // fix ie6 problem when blocked element has a border width
                    if (expr) {
                        bw = sz(this,‘borderLeftWidth‘) + sz(this,‘borderRightWidth‘);
                        ds.setExpression(‘width‘, ‘this.parentNode.offsetWidth - ‘+bw+‘+ "px"‘);
                    }
                    else
                        ds.width = ‘100%‘;
                }
                else {
                    ds.position = ‘relative‘;
                    ds.margin = !bot ? ‘-‘+pad.T+‘px -‘+pad.R+‘px ‘+(pad.T-width)+‘px -‘+pad.L+‘px‘ : 
                                        (pad.B-width)+‘px -‘+pad.R+‘px -‘+pad.B+‘px -‘+pad.L+‘px‘;                
                }

                for (i=0; i < width; i++) {
                    w = Math.max(0,getWidth(fx,i, width));
                    e = strip.cloneNode(false);
                    e.style.borderWidth = ‘0 ‘+(opts[j+‘R‘]?w:0)+‘px 0 ‘+(opts[j+‘L‘]?w:0)+‘px‘;
                    bot ? d.appendChild(e) : d.insertBefore(e, d.firstChild);
                }
                
                if (fold && $.support.boxModel) {
                    if (bot && noBottomFold) continue;
                    for (c in opts) {
                        if (!opts[c]) continue;
                        if (bot && (c == ‘TL‘ || c == ‘TR‘)) continue;
                        if (!bot && (c == ‘BL‘ || c == ‘BR‘)) continue;
                        
                        common = { position: ‘absolute‘, border: ‘none‘, margin: 0, padding: 0, overflow: ‘hidden‘, backgroundColor: strip.style.borderColor };
                        $horz = $(‘<div/>‘).css(common).css({ width: width + ‘px‘, height: ‘1px‘ });
                        switch(c) {
                        case ‘TL‘: $horz.css({ bottom: 0, left: 0 }); break;
                        case ‘TR‘: $horz.css({ bottom: 0, right: 0 }); break;
                        case ‘BL‘: $horz.css({ top: 0, left: 0 }); break;
                        case ‘BR‘: $horz.css({ top: 0, right: 0 }); break;
                        }
                        d.appendChild($horz[0]);
                        
                        var $vert = $(‘<div/>‘).css(common).css({ top: 0, bottom: 0, width: ‘1px‘, height: width + ‘px‘ });
                        switch(c) {
                        case ‘TL‘: $vert.css({ left: width }); break;
                        case ‘TR‘: $vert.css({ right: width }); break;
                        case ‘BL‘: $vert.css({ left: width }); break;
                        case ‘BR‘: $vert.css({ right: width }); break;
                        }
                        d.appendChild($vert[0]);
                    }
                }
            }
        }
    });
};

$.fn.uncorner = function() { 
    if (radius || moz || webkit)
        this.css(radius ? ‘border-radius‘ : moz ? ‘-moz-border-radius‘ : ‘-webkit-border-radius‘, 0);
    $(‘div.jquery-corner‘, this).remove();
    return this;
};

// expose options
$.fn.corner.defaults = {
    useNative: true, // true if plugin should attempt to use native browser support for border radius rounding
    metaAttr:  ‘data-corner‘ // name of meta attribute to use for options
};
    
})(jQuery);
View Code
技术分享
/**
 * jQuery Roundabout - v2.4.2
 * http://fredhq.com/projects/roundabout
 *
 * Moves list-items of enabled ordered and unordered lists long
 * a chosen path. Includes the default "lazySusan" path, that
 * moves items long a spinning turntable.
 *
 * Terms of Use // jQuery Roundabout
 *
 * Open source under the BSD license
 *
 * Copyright (c) 2011-2012, Fred LeBlanc
 * 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 its 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 HOLDER 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.
 */
(function($) {
    "use strict";
    
    var defaults, internalData, methods;

    // add default shape
    $.extend({
        roundaboutShapes: {
            def: "lazySusan",
            lazySusan: function (r, a, t) {
                return {
                    x: Math.sin(r + a),
                    y: (Math.sin(r + 3 * Math.PI / 2 + a) / 8) * t,
                    z: (Math.cos(r + a) + 1) / 2,
                    scale: (Math.sin(r + Math.PI / 2 + a) / 2) + 0.5
                };
            }
        }
    });

    defaults = {
        bearing: 0.0,
        tilt: 0.0,
        minZ: 100,
        maxZ: 280,
        minOpacity: 0.4,
        maxOpacity: 1.0,
        minScale: 0.4,
        maxScale: 1.0,
        duration: 600,
        btnNext: null,
        btnNextCallback: function() {},
        btnPrev: null,
        btnPrevCallback: function() {},
        btnToggleAutoplay: null,
        btnStartAutoplay: null,
        btnStopAutoplay: null,
        easing: "swing",
        clickToFocus: true,
        clickToFocusCallback: function() {},
        focusBearing: 0.0,
        shape: "lazySusan",
        debug: false,
        childSelector: "li",
        startingChild: null,
        reflect: false,
        floatComparisonThreshold: 0.001,
        autoplay: false,
        autoplayDuration: 1000,
        autoplayPauseOnHover: false,
        autoplayCallback: function() {},
        autoplayInitialDelay: 0,
        enableDrag: false,
        dropDuration: 600,
        dropEasing: "swing",
        dropAnimateTo: "nearest",
        dropCallback: function() {},
        dragAxis: "x",
        dragFactor: 4,
        triggerFocusEvents: true,
        triggerBlurEvents: true,
        responsive: false
    };

    internalData = {
        autoplayInterval: null,
        autoplayIsRunning: false,
        autoplayStartTimeout: null,
        animating: false,
        childInFocus: -1,
        touchMoveStartPosition: null,
        stopAnimation: false,
        lastAnimationStep: false
    };

    methods = {

        // starters
        // -----------------------------------------------------------------------

        // init
        // starts up roundabout
        init: function(options, callback, relayout) {
            var settings,
                now = (new Date()).getTime();

            options   = (typeof options === "object") ? options : {};
            callback  = ($.isFunction(callback)) ? callback : function() {};
            callback  = ($.isFunction(options)) ? options : callback;
            settings  = $.extend({}, defaults, options, internalData);

            return this
                .each(function() {
                    // make options
                    var self = $(this),
                        childCount = self.children(settings.childSelector).length,
                        period = 360.0 / childCount,
                        startingChild = (settings.startingChild && settings.startingChild > (childCount - 1)) ? (childCount - 1) : settings.startingChild,
                        startBearing = (settings.startingChild === null) ? settings.bearing : 360 - (startingChild * period),
                        holderCSSPosition = (self.css("position") !== "static") ? self.css("position") : "relative";

                    self
                        .css({  // starting styles
                            padding:   0,
                            position:  holderCSSPosition
                        })
                        .addClass("roundabout-holder")
                        .data(  // starting options
                            "roundabout",
                            $.extend(
                                {},
                                settings,
                                {
                                    startingChild: startingChild,
                                    bearing: startBearing,
                                    oppositeOfFocusBearing: methods.normalize.apply(null, [settings.focusBearing - 180]),
                                    dragBearing: startBearing,
                                    period: period
                                }
                            )
                        );

                    // unbind any events that we set if we‘re relaying out
                    if (relayout) {
                        self
                            .unbind(".roundabout")
                            .children(settings.childSelector)
                                .unbind(".roundabout");
                    } else {
                        // bind responsive action
                        if (settings.responsive) {
                            $(window).bind("resize", function() {
                                methods.stopAutoplay.apply(self);
                                methods.relayoutChildren.apply(self);
                            });
                        }
                    }

                    // bind click-to-focus
                    if (settings.clickToFocus) {
                        self
                            .children(settings.childSelector)
                            .each(function(i) {
                                $(this)
                                    .bind("click.roundabout", function() {
                                        var degrees = methods.getPlacement.apply(self, [i]);

                                        if (!methods.isInFocus.apply(self, [degrees])) {
                                            methods.stopAnimation.apply($(this));
                                            if (!self.data("roundabout").animating) {
                                                methods.animateBearingToFocus.apply(self, [degrees, self.data("roundabout").clickToFocusCallback]);
                                            }
                                            return false;
                                        }
                                    });
                            });
                    }

                    // bind next buttons
                    if (settings.btnNext) {
                        $(settings.btnNext)
                            .bind("click.roundabout", function() {
                                if (!self.data("roundabout").animating) {
                                    methods.animateToNextChild.apply(self, [self.data("roundabout").btnNextCallback]);
                                }
                                return false;
                            });
                    }

                    // bind previous buttons
                    if (settings.btnPrev) {
                        $(settings.btnPrev)
                            .bind("click.roundabout", function() {
                                methods.animateToPreviousChild.apply(self, [self.data("roundabout").btnPrevCallback]);
                                return false;
                            });
                    }

                    // bind toggle autoplay buttons
                    if (settings.btnToggleAutoplay) {
                        $(settings.btnToggleAutoplay)
                            .bind("click.roundabout", function() {
                                methods.toggleAutoplay.apply(self);
                                return false;
                            });
                    }

                    // bind start autoplay buttons
                    if (settings.btnStartAutoplay) {
                        $(settings.btnStartAutoplay)
                            .bind("click.roundabout", function() {
                                methods.startAutoplay.apply(self);
                                return false;
                            });
                    }

                    // bind stop autoplay buttons
                    if (settings.btnStopAutoplay) {
                        $(settings.btnStopAutoplay)
                            .bind("click.roundabout", function() {
                                methods.stopAutoplay.apply(self);
                                return false;
                            });
                    }

                    // autoplay pause on hover
                    if (settings.autoplayPauseOnHover) {
                        self
                            .bind("mouseenter.roundabout.autoplay", function() {
                                methods.stopAutoplay.apply(self, [true]);
                            })
                            .bind("mouseleave.roundabout.autoplay", function() {
                                methods.startAutoplay.apply(self);
                            });
                    }

                    // drag and drop
                    if (settings.enableDrag) {
                        // on screen
                        if (!$.isFunction(self.drag)) {
                            if (settings.debug) {
                                alert("You do not have the drag plugin loaded.");
                            }
                        } else if (!$.isFunction(self.drop)) {
                            if (settings.debug) {
                                alert("You do not have the drop plugin loaded.");
                            }
                        } else {
                            self
                                .drag(function(e, properties) {
                                    var data = self.data("roundabout"),
                                        delta = (data.dragAxis.toLowerCase() === "x") ? "deltaX" : "deltaY";
                                    methods.stopAnimation.apply(self);
                                    methods.setBearing.apply(self, [data.dragBearing + properties[delta] / data.dragFactor]);
                                })
                                .drop(function(e) {
                                    var data = self.data("roundabout"),
                                        method = methods.getAnimateToMethod(data.dropAnimateTo);
                                    methods.allowAnimation.apply(self);
                                    methods[method].apply(self, [data.dropDuration, data.dropEasing, data.dropCallback]);
                                    data.dragBearing = data.period * methods.getNearestChild.apply(self);
                                });
                        }

                        // on mobile
                        self
                            .each(function() {
                                var element = $(this).get(0),
                                    data = $(this).data("roundabout"),
                                    page = (data.dragAxis.toLowerCase() === "x") ? "pageX" : "pageY",
                                    method = methods.getAnimateToMethod(data.dropAnimateTo);

                                // some versions of IE don‘t like this
                                if (element.addEventListener) {
                                    element.addEventListener("touchstart", function(e) {
                                        data.touchMoveStartPosition = e.touches[0][page];
                                    }, false);

                                    element.addEventListener("touchmove", function(e) {
                                        var delta = (e.touches[0][page] - data.touchMoveStartPosition) / data.dragFactor;
                                        e.preventDefault();
                                        methods.stopAnimation.apply($(this));
                                        methods.setBearing.apply($(this), [data.dragBearing + delta]);
                                    }, false);

                                    element.addEventListener("touchend", function(e) {
                                        e.preventDefault();
                                        methods.allowAnimation.apply($(this));
                                        method = methods.getAnimateToMethod(data.dropAnimateTo);
                                        methods[method].apply($(this), [data.dropDuration, data.dropEasing, data.dropCallback]);
                                        data.dragBearing = data.period * methods.getNearestChild.apply($(this));
                                    }, false);
                                }
                            });
                    }

                    // start children
                    methods.initChildren.apply(self, [callback, relayout]);
                });
        },


        // initChildren
        // applys settings to child elements, starts roundabout
        initChildren: function(callback, relayout) {
            var self = $(this),
                data = self.data("roundabout");

            callback = callback || function() {};
            
            self.children(data.childSelector).each(function(i) {
                var startWidth, startHeight, startFontSize,
                    degrees = methods.getPlacement.apply(self, [i]);

                // on relayout, grab these values from current data
                if (relayout && $(this).data("roundabout")) {
                    startWidth = $(this).data("roundabout").startWidth;
                    startHeight = $(this).data("roundabout").startHeight;
                    startFontSize = $(this).data("roundabout").startFontSize;
                }

                // apply classes and css first
                $(this)
                    .addClass("roundabout-moveable-item")
                    .css("position", "absolute");

                // now measure
                $(this)
                    .data(
                        "roundabout",
                        {
                            startWidth: startWidth || $(this).width(),
                            startHeight: startHeight || $(this).height(),
                            startFontSize: startFontSize || parseInt($(this).css("font-size"), 10),
                            degrees: degrees,
                            backDegrees: methods.normalize.apply(null, [degrees - 180]),
                            childNumber: i,
                            currentScale: 1,
                            parent: self
                        }
                    );
            });

            methods.updateChildren.apply(self);

            // start autoplay if necessary
            if (data.autoplay) {
                data.autoplayStartTimeout = setTimeout(function() {
                    methods.startAutoplay.apply(self);
                }, data.autoplayInitialDelay);
            }

            self.trigger(‘ready‘);
            callback.apply(self);
            return self;
        },



        // positioning
        // -----------------------------------------------------------------------

        // updateChildren
        // move children elements into their proper locations
        updateChildren: function() {
            return this
                .each(function() {
                    var self = $(this),
                        data = self.data("roundabout"),
                        inFocus = -1,
                        info = {
                            bearing: data.bearing,
                            tilt: data.tilt,
                            stage: {
                                width: Math.floor($(this).width() * 0.9),
                                height: Math.floor($(this).height() * 0.9)
                            },
                            animating: data.animating,
                            inFocus: data.childInFocus,
                            focusBearingRadian: methods.degToRad.apply(null, [data.focusBearing]),
                            shape: $.roundaboutShapes[data.shape] || $.roundaboutShapes[$.roundaboutShapes.def]
                        };

                    // calculations
                    info.midStage = {
                        width: info.stage.width / 2,
                        height: info.stage.height / 2
                    };

                    info.nudge = {
                        width: info.midStage.width + (info.stage.width * 0.05),
                        height: info.midStage.height + (info.stage.height * 0.05)
                    };

                    info.zValues = {
                        min: data.minZ,
                        max: data.maxZ,
                        diff: data.maxZ - data.minZ
                    };

                    info.opacity = {
                        min: data.minOpacity,
                        max: data.maxOpacity,
                        diff: data.maxOpacity - data.minOpacity
                    };

                    info.scale = {
                        min: data.minScale,
                        max: data.maxScale,
                        diff: data.maxScale - data.minScale
                    };

                    // update child positions
                    self.children(data.childSelector)
                        .each(function(i) {
                            if (methods.updateChild.apply(self, [$(this), info, i, function() { $(this).trigger(‘ready‘); }]) && (!info.animating || data.lastAnimationStep)) {
                                inFocus = i;
                                $(this).addClass("roundabout-in-focus");
                            } else {
                                $(this).removeClass("roundabout-in-focus");
                            }
                        });

                    if (inFocus !== info.inFocus) {
                        // blur old child
                        if (data.triggerBlurEvents) {
                            self.children(data.childSelector)
                                .eq(info.inFocus)
                                    .trigger("blur");
                        }

                        data.childInFocus = inFocus;

                        if (data.triggerFocusEvents && inFocus !== -1) {
                            // focus new child
                            self.children(data.childSelector)
                                .eq(inFocus)
                                    .trigger("focus");
                        }
                    }

                    self.trigger("childrenUpdated");
                });
        },


        // updateChild
        // repositions a child element into its new position
        updateChild: function(childElement, info, childPos, callback) {
            var factors,
                self = this,
                child = $(childElement),
                data = child.data("roundabout"),
                out = [],
                rad = methods.degToRad.apply(null, [(360.0 - data.degrees) + info.bearing]);

            callback = callback || function() {};

            // adjust radians to be between 0 and Math.PI * 2
            rad = methods.normalizeRad.apply(null, [rad]);

            // get factors from shape
            factors = info.shape(rad, info.focusBearingRadian, info.tilt);

            // correct
            factors.scale = (factors.scale > 1) ? 1 : factors.scale;
            factors.adjustedScale = (info.scale.min + (info.scale.diff * factors.scale)).toFixed(4);
            factors.width = (factors.adjustedScale * data.startWidth).toFixed(4);
            factors.height = (factors.adjustedScale * data.startHeight).toFixed(4);

            // update item
            child
                .css({
                    left: ((factors.x * info.midStage.width + info.nudge.width) - factors.width / 2.0).toFixed(0) + "px",
                    top: ((factors.y * info.midStage.height + info.nudge.height) - factors.height / 2.0).toFixed(0) + "px",
                    width: factors.width + "px",
                    height: factors.height + "px",
                    opacity: (info.opacity.min + (info.opacity.diff * factors.scale)).toFixed(2),
                    zIndex: Math.round(info.zValues.min + (info.zValues.diff * factors.z)),
                    fontSize: (factors.adjustedScale * data.startFontSize).toFixed(1) + "px"
                });
            data.currentScale = factors.adjustedScale;

            // for debugging purposes
            if (self.data("roundabout").debug) {
                out.push("<div style=\"font-weight: normal; font-size: 10px; padding: 2px; width: " + child.css("width") + "; background-color: #ffc;\">");
                out.push("<strong style=\"font-size: 12px; white-space: nowrap;\">Child " + childPos + "</strong><br />");
                out.push("<strong>left:</strong> " + child.css("left") + "<br />");
                out.push("<strong>top:</strong> " + child.css("top") + "<br />");
                out.push("<strong>width:</strong> " + child.css("width") + "<br />");
                out.push("<strong>opacity:</strong> " + child.css("opacity") + "<br />");
                out.push("<strong>height:</strong> " + child.css("height") + "<br />");
                out.push("<strong>z-index:</strong> " + child.css("z-index") + "<br />");
                out.push("<strong>font-size:</strong> " + child.css("font-size") + "<br />");
                out.push("<strong>scale:</strong> " + child.data("roundabout").currentScale);
                out.push("</div>");

                child.html(out.join(""));
            }

            // trigger event
            child.trigger("reposition");
            
            // callback
            callback.apply(self);

            return methods.isInFocus.apply(self, [data.degrees]);
        },



        // manipulation
        // -----------------------------------------------------------------------

        // setBearing
        // changes the bearing of the roundabout
        setBearing: function(bearing, callback) {
            callback = callback || function() {};
            bearing = methods.normalize.apply(null, [bearing]);

            this
                .each(function() {
                    var diff, lowerValue, higherValue,
                        self = $(this),
                        data = self.data("roundabout"),
                        oldBearing = data.bearing;

                    // set bearing
                    data.bearing = bearing;
                    self.trigger("bearingSet");
                    methods.updateChildren.apply(self);

                    // not animating? we‘re done here
                    diff = Math.abs(oldBearing - bearing);
                    if (!data.animating || diff > 180) {
                        return;
                    }

                    // check to see if any of the children went through the back
                    diff = Math.abs(oldBearing - bearing);
                    self.children(data.childSelector).each(function(i) {
                        var eventType;

                        if (methods.isChildBackDegreesBetween.apply($(this), [bearing, oldBearing])) {
                            eventType = (oldBearing > bearing) ? "Clockwise" : "Counterclockwise";
                            $(this).trigger("move" + eventType + "ThroughBack");
                        }
                    });
                });

            // call callback if one was given
            callback.apply(this);
            return this;
        },


        // adjustBearing
        // change the bearing of the roundabout by a given degree
        adjustBearing: function(delta, callback) {
            callback = callback || function() {};
            if (delta === 0) {
                return this;
            }

            this
                .each(function() {
                    methods.setBearing.apply($(this), [$(this).data("roundabout").bearing + delta]);
                });

            callback.apply(this);
            return this;
        },


        // setTilt
        // changes the tilt of the roundabout
        setTilt: function(tilt, callback) {
            callback = callback || function() {};

            this
                .each(function() {
                    $(this).data("roundabout").tilt = tilt;
                    methods.updateChildren.apply($(this));
                });

            // call callback if one was given
            callback.apply(this);
            return this;
        },


        // adjustTilt
        // changes the tilt of the roundabout
        adjustTilt: function(delta, callback) {
            callback = callback || function() {};

            this
                .each(function() {
                    methods.setTilt.apply($(this), [$(this).data("roundabout").tilt + delta]);
                });

            callback.apply(this);
            return this;
        },



        // animation
        // -----------------------------------------------------------------------

        // animateToBearing
        // animates the roundabout to a given bearing, all animations come through here
        animateToBearing: function(bearing, duration, easing, passedData, callback) {
            var now = (new Date()).getTime();

            callback = callback || function() {};

            // find callback function in arguments
            if ($.isFunction(passedData)) {
                callback = passedData;
                passedData = null;
            } else if ($.isFunction(easing)) {
                callback = easing;
                easing = null;
            } else if ($.isFunction(duration)) {
                callback = duration;
                duration = null;
            }

            this
                .each(function() {
                    var timer, easingFn, newBearing,
                        self = $(this),
                        data = self.data("roundabout"),
                        thisDuration = (!duration) ? data.duration : duration,
                        thisEasingType = (easing) ? easing : data.easing || "swing";

                    // is this your first time?
                    if (!passedData) {
                        passedData = {
                            timerStart: now,
                            start: data.bearing,
                            totalTime: thisDuration
                        };
                    }

                    // update the timer
                    timer = now - passedData.timerStart;

                    if (data.stopAnimation) {
                        methods.allowAnimation.apply(self);
                        data.animating = false;
                        return;
                    }

                    // we need to animate more
                    if (timer < thisDuration) {
                        if (!data.animating) {
                            self.trigger("animationStart");
                        }

                        data.animating = true;

                        if (typeof $.easing.def === "string") {
                            easingFn = $.easing[thisEasingType] || $.easing[$.easing.def];
                            newBearing = easingFn(null, timer, passedData.start, bearing - passedData.start, passedData.totalTime);
                        } else {
                            newBearing = $.easing[thisEasingType]((timer / passedData.totalTime), timer, passedData.start, bearing - passedData.start, passedData.totalTime);
                        }

                        // fixes issue #24, animation changed as of jQuery 1.7.2
                        // also addresses issue #29, using easing breaks "linear"
                        if (methods.compareVersions.apply(null, [$().jquery, "1.7.2"]) >= 0 && !($.easing["easeOutBack"])) {
                            newBearing = passedData.start + ((bearing - passedData.start) * newBearing);
                        }

                        newBearing = methods.normalize.apply(null, [newBearing]);
                        data.dragBearing = newBearing;

                        methods.setBearing.apply(self, [newBearing, function() {
                            setTimeout(function() {  // done with a timeout so that each step is displayed
                                methods.animateToBearing.apply(self, [bearing, thisDuration, thisEasingType, passedData, callback]);
                            }, 0);
                        }]);

                    // we‘re done animating
                    } else {
                        data.lastAnimationStep = true;

                        bearing = methods.normalize.apply(null, [bearing]);
                        methods.setBearing.apply(self, [bearing, function() {
                            self.trigger("animationEnd");
                        }]);
                        data.animating = false;
                        data.lastAnimationStep = false;
                        data.dragBearing = bearing;

                        callback.apply(self);
                    }
                });

            return this;
        },


        // animateToNearbyChild
        // animates roundabout to a nearby child
        animateToNearbyChild: function(passedArgs, which) {
            var duration = passedArgs[0],
                easing = passedArgs[1],
                callback = passedArgs[2] || function() {};

            // find callback
            if ($.isFunction(easing)) {
                callback = easing;
                easing = null;
            } else if ($.isFunction(duration)) {
                callback = duration;
                duration = null;
            }

            return this
                .each(function() {
                    var j, range,
                        self = $(this),
                        data = self.data("roundabout"),
                        bearing = (!data.reflect) ? data.bearing % 360 : data.bearing,
                        length = self.children(data.childSelector).length;

                    if (!data.animating) {
                        // reflecting, not moving to previous || not reflecting, moving to next
                        if ((data.reflect && which === "previous") || (!data.reflect && which === "next")) {
                            // slightly adjust for rounding issues
                            bearing = (Math.abs(bearing) < data.floatComparisonThreshold) ? 360 : bearing;

                            // clockwise
                            for (j = 0; j < length; j += 1) {
                                range = {
                                    lower: (data.period * j),
                                    upper: (data.period * (j + 1))
                                };
                                range.upper = (j === length - 1) ? 360 : range.upper;

                                if (bearing <= Math.ceil(range.upper) && bearing >= Math.floor(range.lower)) {
                                    if (length === 2 && bearing === 360) {
                                        methods.animateToDelta.apply(self, [-180, duration, easing, callback]);
                                    } else {
                                        methods.animateBearingToFocus.apply(self, [range.lower, duration, easing, callback]);
                                    }
                                    break;
                                }
                            }
                        } else {
                            // slightly adjust for rounding issues
                            bearing = (Math.abs(bearing) < data.floatComparisonThreshold || 360 - Math.abs(bearing) < data.floatComparisonThreshold) ? 0 : bearing;

                            // counterclockwise
                            for (j = length - 1; j >= 0; j -= 1) {
                                range = {
                                    lower: data.period * j,
                                    upper: data.period * (j + 1)
                                };
                                range.upper = (j === length - 1) ? 360 : range.upper;

                                if (bearing >= Math.floor(range.lower) && bearing < Math.ceil(range.upper)) {
                                    if (length === 2 && bearing === 360) {
                                        methods.animateToDelta.apply(self, [180, duration, easing, callback]);
                                    } else {
                                        methods.animateBearingToFocus.apply(self, [range.upper, duration, easing, callback]);
                                    }
                                    break;
                                }
                            }
                        }
                    }
                });
        },


        // animateToNearestChild
        // animates roundabout to the nearest child
        animateToNearestChild: function(duration, easing, callback) {
            callback = callback || function() {};

            // find callback
            if ($.isFunction(easing)) {
                callback = easing;
                easing = null;
            } else if ($.isFunction(duration)) {
                callback = duration;
                duration = null;
            }

            return this
                .each(function() {
                    var nearest = methods.getNearestChild.apply($(this));
                    methods.animateToChild.apply($(this), [nearest, duration, easing, callback]);
                });
        },


        // animateToChild
        // animates roundabout to a given child position
        animateToChild: function(childPosition, duration, easing, callback) {
            callback = callback || function() {};

            // find callback
            if ($.isFunction(easing)) {
                callback = easing;
                easing = null;
            } else if ($.isFunction(duration)) {
                callback = duration;
                duration = null;
            }

            return this
                .each(function() {
                    var child,
                        self = $(this),
                        data = self.data("roundabout");

                    if (data.childInFocus !== childPosition && !data.animating) {
                        child = self.children(data.childSelector).eq(childPosition);
                        methods.animateBearingToFocus.apply(self, [child.data("roundabout").degrees, duration, easing, callback]);
                    }
                });
        },


        // animateToNextChild
        // animates roundabout to the next child
        animateToNextChild: function(duration, easing, callback) {
            return methods.animateToNearbyChild.apply(this, [arguments, "next"]);
        },


        // animateToPreviousChild
        // animates roundabout to the preious child
        animateToPreviousChild: function(duration, easing, callback) {
            return methods.animateToNearbyChild.apply(this, [arguments, "previous"]);
        },


        // animateToDelta
        // animates roundabout to a given delta (in degrees)
        animateToDelta: function(degrees, duration, easing, callback) {
            callback = callback || function() {};

            // find callback
            if ($.isFunction(easing)) {
                callback = easing;
                easing = null;
            } else if ($.isFunction(duration)) {
                callback = duration;
                duration = null;
            }

            return this
                .each(function() {
                    var delta = $(this).data("roundabout").bearing + degrees;
                    methods.animateToBearing.apply($(this), [delta, duration, easing, callback]);
                });
        },


        // animateBearingToFocus
        // animates roundabout to bring a given angle into focus
        animateBearingToFocus: function(degrees, duration, easing, callback) {
            callback = callback || function() {};

            // find callback
            if ($.isFunction(easing)) {
                callback = easing;
                easing = null;
            } else if ($.isFunction(duration)) {
                callback = duration;
                duration = null;
            }

            return this
                .each(function() {
                    var delta = $(this).data("roundabout").bearing - degrees;
                    delta = (Math.abs(360 - delta) < Math.abs(delta)) ? 360 - delta : -delta;
                    delta = (delta > 180) ? -(360 - delta) : delta;

                    if (delta !== 0) {
                        methods.animateToDelta.apply($(this), [delta, duration, easing, callback]);
                    }
                });
        },


        // stopAnimation
        // if an animation is currently in progress, stop it
        stopAnimation: function() {
            return this
                .each(function() {
                    $(this).data("roundabout").stopAnimation = true;
                });
        },


        // allowAnimation
        // clears the stop-animation hold placed by stopAnimation
        allowAnimation: function() {
            return this
                .each(function() {
                    $(this).data("roundabout").stopAnimation = false;
                });
        },



        // autoplay
        // -----------------------------------------------------------------------

        // startAutoplay
        // starts autoplaying this roundabout
        startAutoplay: function(callback) {
            return this
                .each(function() {
                    var self = $(this),
                        data = self.data("roundabout");

                    callback = callback || data.autoplayCallback || function() {};

                    clearInterval(data.autoplayInterval);
                    data.autoplayInterval = setInterval(function() {
                        methods.animateToNextChild.apply(self, [callback]);
                    }, data.autoplayDuration);
                    data.autoplayIsRunning = true;
                    
                    self.trigger("autoplayStart");
                });
        },


        // stopAutoplay
        // stops autoplaying this roundabout
        stopAutoplay: function(keepAutoplayBindings) {
            return this
                .each(function() {
                    clearInterval($(this).data("roundabout").autoplayInterval);
                    $(this).data("roundabout").autoplayInterval = null;
                    $(this).data("roundabout").autoplayIsRunning = false;
                    
                    // this will prevent autoplayPauseOnHover from restarting autoplay
                    if (!keepAutoplayBindings) {
                        $(this).unbind(".autoplay");
                    }
                    
                    $(this).trigger("autoplayStop");
                });
        },
        
        
        // toggleAutoplay
        // toggles autoplay pause/resume
        toggleAutoplay: function(callback) {
            return this
                .each(function() {
                    var self = $(this),
                        data = self.data("roundabout");

                    callback = callback || data.autoplayCallback || function() {};

                    if (!methods.isAutoplaying.apply($(this))) {
                        methods.startAutoplay.apply($(this), [callback]);
                    } else {
                        methods.stopAutoplay.apply($(this), [callback]);
                    }
                });
        },


        // isAutoplaying
        // is this roundabout currently autoplaying?
        isAutoplaying: function() {
            return (this.data("roundabout").autoplayIsRunning);
        },


        // changeAutoplayDuration
        // stops the autoplay, changes the duration, restarts autoplay
        changeAutoplayDuration: function(duration) {
            return this
                .each(function() {
                    var self = $(this),
                        data = self.data("roundabout");

                    data.autoplayDuration = duration;

                    if (methods.isAutoplaying.apply(self)) {
                        methods.stopAutoplay.apply(self);
                        setTimeout(function() {
                            methods.startAutoplay.apply(self);
                        }, 10);
                    }
                });
        },



        // helpers
        // -----------------------------------------------------------------------

        // normalize
        // regulates degrees to be >= 0.0 and < 360
        normalize: function(degrees) {
            var inRange = degrees % 360.0;
            return (inRange < 0) ? 360 + inRange : inRange;
        },


        // normalizeRad
        // regulates radians to be >= 0 and < Math.PI * 2
        normalizeRad: function(radians) {
            while (radians < 0) {
                radians += (Math.PI * 2);
            }

            while (radians > (Math.PI * 2)) {
                radians -= (Math.PI * 2);
            }

            return radians;
        },


        // isChildBackDegreesBetween
        // checks that a given child‘s backDegrees is between two values
        isChildBackDegreesBetween: function(value1, value2) {
            var backDegrees = $(this).data("roundabout").backDegrees;

            if (value1 > value2) {
                return (backDegrees >= value2 && backDegrees < value1);
            } else {
                return (backDegrees < value2 && backDegrees >= value1);
            }
        },


        // getAnimateToMethod
        // takes a user-entered option and maps it to an animation method
        getAnimateToMethod: function(effect) {
            effect = effect.toLowerCase();

            if (effect === "next") {
                return "animateToNextChild";
            } else if (effect === "previous") {
                return "animateToPreviousChild";
            }

            // default selection
            return "animateToNearestChild";
        },
        
        
        // relayoutChildren
        // lays out children again with new contextual information
        relayoutChildren: function() {
            return this
                .each(function() {
                    var self = $(this),
                        settings = $.extend({}, self.data("roundabout"));

                    settings.startingChild = self.data("roundabout").childInFocus;
                    methods.init.apply(self, [settings, null, true]);
                });
        },


        // getNearestChild
        // gets the nearest child from the current bearing
        getNearestChild: function() {
            var self = $(this),
                data = self.data("roundabout"),
                length = self.children(data.childSelector).length;

            if (!data.reflect) {
                return ((length) - (Math.round(data.bearing / data.period) % length)) % length;
            } else {
                return (Math.round(data.bearing / data.period) % length);
            }
        },


        // degToRad
        // converts degrees to radians
        degToRad: function(degrees) {
            return methods.normalize.apply(null, [degrees]) * Math.PI / 180.0;
        },


        // getPlacement
        // returns the starting degree for a given child
        getPlacement: function(child) {
            var data = this.data("roundabout");
            return (!data.reflect) ? 360.0 - (data.period * child) : data.period * child;
        },


        // isInFocus
        // is this roundabout currently in focus?
        isInFocus: function(degrees) {
            var diff,
                self = this,
                data = self.data("roundabout"),
                bearing = methods.normalize.apply(null, [data.bearing]);

            degrees = methods.normalize.apply(null, [degrees]);
            diff = Math.abs(bearing - degrees);

            // this calculation gives a bit of room for javascript float rounding
            // errors, it looks on both 0deg and 360deg ends of the spectrum
            return (diff <= data.floatComparisonThreshold || diff >= 360 - data.floatComparisonThreshold);
        },
        
        
        // getChildInFocus
        // returns the current child in focus, or false if none are in focus
        getChildInFocus: function() {
            var data = $(this).data("roundabout");
            
            return (data.childInFocus > -1) ? data.childInFocus : false;
        },


        // compareVersions
        // compares a given version string with another
        compareVersions: function(baseVersion, compareVersion) {
            var i,
                base = baseVersion.split(/\./i),
                compare = compareVersion.split(/\./i),
                maxVersionSegmentLength = (base.length > compare.length) ? base.length : compare.length;

            for (i = 0; i <= maxVersionSegmentLength; i++) {
                if (base[i] && !compare[i] && parseInt(base[i], 10) !== 0) {
                    // base is higher
                    return 1;
                } else if (compare[i] && !base[i] && parseInt(compare[i], 10) !== 0) {
                    // compare is higher
                    return -1;
                } else if (base[i] === compare[i]) {
                    // these are the same, next
                    continue;
                }

                if (base[i] && compare[i]) {
                    if (parseInt(base[i], 10) > parseInt(compare[i], 10)) {
                        // base is higher
                        return 1;
                    } else {
                        // compare is higher
                        return -1;
                    }
                }
            }

            // nothing was triggered, versions are the same
            return 0;
        }
    };


    // start the plugin
    $.fn.roundabout = function(method) {
        if (methods[method]) {
            return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
        } else if (typeof method === "object" || $.isFunction(method) || !method) {
            return methods.init.apply(this, arguments);
        } else {
            $.error("Method " + method + " does not exist for jQuery.roundabout.");
        }
    };
})(jQuery);
View Code
技术分享
/**
 * jQuery Roundabout Shapes v2
 * http://fredhq.com/projects/roundabout-shapes/
 * 
 * Provides additional paths along which items can move for the
 * jQuery Roundabout plugin (v1.0+).
 *
 * Terms of Use // jQuery Roundabout Shapes
 *
 * Open source under the BSD license
 *
 * Copyright (c) 2009-2011, Fred LeBlanc
 * 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 its 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 HOLDER 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.extend(jQuery.roundaboutShapes,
{
    theJuggler: function(r, a, t) {    
        return {
            x: Math.sin(r + a), 
            y: Math.tan(Math.exp(Math.log(r)) + a) / (t - 1), 
            z: (Math.cos(r + a) + 1) / 2,
            scale: (Math.sin(r + Math.PI/2 + a) / 2) + 0.5
        };
    },
    figure8: function(r, a, t) {
        return {
            x: Math.sin(r * 2 + a), 
            y: (Math.sin(r + Math.PI/2 + a) / 8) * t, 
            z: (Math.cos(r + a) + 1) / 2,
            scale: (Math.sin(r + Math.PI/2 + a) / 2) + 0.5
        };
    },
    waterWheel: function(r, a, t) {
        return {
            x: (Math.sin(r + Math.PI/2 + a) / 8) * t, 
            y: Math.sin(r + a) / (Math.PI/2), 
            z: (Math.cos(r + a) + 1) / 2,
            scale: (Math.sin(r + Math.PI/2 + a) / 2) + 0.5
        };
    },
    square: function(r, a, t) {
        var sq_x, sq_y, sq_z;
        
        if (r <= Math.PI/2) {
            sq_x = (2/Math.PI) * r;
            sq_y = -(2/Math.PI) * r + 1;
            sq_z = -(1/Math.PI) * r + 1;
        } else if (r > Math.PI/2 && r <= Math.PI) {
            sq_x = -(2/Math.PI) * r + 2;
            sq_y = -(2/Math.PI) * r + 1;
            sq_z = -(1/Math.PI) * r + 1;
        } else if (r > Math.PI && r <= (3 * Math.PI) / 2) {
            sq_x = -(2/Math.PI) * r + 2;
            sq_y = (2/Math.PI) * r - 3;
            sq_z = (1/Math.PI) * r - 1;
        } else {
            sq_x = (2/Math.PI) * r - 4;
            sq_y = (2/Math.PI) * r - 3;
            sq_z = (1/Math.PI) * r - 1;
        }
        
        return {
            x: sq_x,
            y: sq_y * t, 
            z: sq_z,
            scale: sq_z
        };
    },
    conveyorBeltLeft: function(r, a, t) {
        return {
            x: -Math.cos(r + a), 
            y: (Math.cos(r + 3*Math.PI/2 + a) / 8) * t, 
            z: (Math.sin(r + a) + 1) / 2,
            scale: (Math.sin(r + Math.PI/2 + a) / 2) + 0.5
        };
    },
    conveyorBeltRight: function(r, a, t) {
        return {
            x: Math.cos(r + a), 
            y: (Math.cos(r + 3*Math.PI/2 + a) / 8) * t, 
            z: (Math.sin(r + a) + 1) / 2,
            scale: (Math.sin(r + Math.PI/2 + a) / 2) + 0.5
        };
    },
    goodbyeCruelWorld: function(r, a, t) {
        return {
            x: Math.sin(r + a), 
            y: (Math.tan(r + 3*Math.PI/2 + a) / 8) * (t + 0.5), 
            z: (Math.sin(r + a) + 1) / 2,
            scale: (Math.sin(r + Math.PI/2 + a) / 2) + 0.5
        };
    },
    diagonalRingLeft: function(r, a, t) {
        return {
            x: Math.sin(r + a), 
            y: -Math.cos(r + Math.tan(Math.cos(a))) / (t + 1.5), 
            z: (Math.cos(r + a) + 1) / 2,
            scale: (Math.sin(r + Math.PI/2 + a) / 2) + 0.5
        };
    },
    diagonalRingRight: function(r, a, t) {
        return {
            x: Math.sin(r + a), 
            y: Math.cos(r + Math.tan(Math.cos(a))) / (t + 1.5), 
            z: (Math.cos(r + a) + 1) / 2,
            scale: (Math.sin(r + Math.PI/2 + a) / 2) + 0.5
        };
    },
    rollerCoaster: function(r, a, t) {
        return {
            x: Math.sin(r + a), 
            y: Math.sin((2 + t) * r), 
            z: (Math.cos(r + a) + 1) / 2,
            scale: (Math.sin(r + Math.PI/2 + a) / 2) + 0.5
        };
    },
    tearDrop: function(r, a, t) {
        return {
            x: Math.sin(r + a), 
            y: -Math.sin(r/2 + t) + 0.35, 
            z: (Math.cos(r + a) + 1) / 2,
            scale: (Math.sin(r + Math.PI/2 + a) / 2) + 0.5
        };
    },
    tickingClock: function(r, a, t) {
        return {
            x: Math.cos(r + a - Math.PI/2),
            y: Math.sin(r + a - Math.PI/2),
            z: Math.cos(r),
            scale: Math.cos(r) + 0.5
        }
    },
    flurry: function(r, a, t) {
        return {
            x: Math.sin(r * 3 + a), 
            y: (Math.cos(r + Math.PI/2 + a) / 2) * t, 
            z: (Math.cos(r + a) + 1) / 2,
            scale: (Math.sin(r + Math.PI/2 + a) / 2) + 0.5
        };
    },
    nowSlide: function(r, a, t) {
        return {
            x: Math.tan(r * 2 + a) * 0.5, 
            y: Math.cos(r*2 + t) / 6, 
            z: (Math.cos(r + a) + 1) / 2,
            scale: (Math.sin(r + Math.PI/2 + a) / 2) + 0.5
        };
    },
    risingEssence: function(r, a, t) {
        return {
            x: Math.sin(r + a), 
            y: Math.tan((2 + t) * r), 
            z: (Math.cos(r + a) + 1) / 2,
            scale: (Math.sin(r + Math.PI/2 + a) / 2) + 0.5
        };
    }
});
View Code

  

#gla{
margin:0 auto;
position:relative;
background:url(../img/gla_bac.png);
height:409px;
overflow:hidden;
}
#gla_box{
width:700px;
margin:auto;
position:relative;}
#gla_box .prev,#gla_box .next{
display:block;
z-index:100;
overflow:hidden;
cursor:pointer;
position:absolute;
width:52px;
height:47px;
top:171px;
}
#gla_box .prev{
background:url(../img/btn.png) left bottom no-repeat;
left:300px;
top:350px;
}
#gla_box .next{
background:url(../img/btn.png) right bottom no-repeat;
right:300px;
top:350px;
}


.gla_inbox{
overflow:hidden;
position:relative;
}
.gla_inbox p{
text-indent:1em;
font-size:14px;
width:100%;
color:#FFFFFF;
line-height:30px;
background:#000000;
}
.gla_inbox a{
padding:5px;
display:block;
position:absolute;
top:220px;
left:90px;
background:#0066CC;
color:#FFF;
}
.gla_inbox img{
width:100%;
height:100%;}

 

<div id="gla">
                <div id="gla_box">
                    <span class="prev">&nbsp;</span>
                    <span class="next">&nbsp;</span>
                    <ul>
                        <li>
                            <div class="gla_inbox">
                                
                                <img src="img/20120814204816.jpg" />
                                
                            </div>
                        </li>
                        <li>
                            <div class="gla_inbox">
                                
                                <img src="img/20120814204750.jpg" />
                                
                            </div>
                        </li>
                        <li>
                            <div class="gla_inbox">
                                
                                <img src="img/20120814204733.jpg" />
                                
                            </div>
                        </li>
                        <li>
                            <div class="gla_inbox">
                                
                                <img src="img/20120814204711.jpg" />
                                
                            </div>
                        </li>
                        <li>
                            <div class="gla_inbox">
                                
                                <img src="img/20120814204658.jpg" />
                                
                            </div>
                        </li>
                    </ul>
                </div>
            </div>
<script type="text/javascript">
$(function(){
           
    $(.gla_inbox).corner(8px);
    
    $(#gla_box>ul).roundabout({
        minOpacity:1,
        btnNext: ".next",
        duration: 1000,
        reflect: true,
        btnPrev: .prev,
        autoplay:true,
        autoplayDuration:5000,
        tilt:0,
        shape: figure8
    });
    
});
</script>

 

js实现左右点击图片层叠滚动特效

标签:

原文地址:http://www.cnblogs.com/baixuemin/p/4956667.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!