这是一款效果十分炫酷的jQuery和css3鼠标滑过网格相邻图片浮动效果。插件中使用了 jQuery Proximity plugin

有很多种方法使用纯css来制作手风琴效果,其中使用最多的是使用:target伪类来实现。使用:target伪类的问题是我们不能够再次关闭内容区域或同时显示多个内容区域。但是通过使用checkbox,我们可以控制内容区域的打开和关闭。如果只想在某一时刻只显示一个内容,可以使用radio按钮来实现。

HTML

下面的例子demo2的html结构:

<ul id="pe-thumbs" class="pe-thumbs">
    <li>
        <a href="#">
            <img src="images/thumbs/1.jpg" />
            <div class="pe-description">
                <h3>Time</h3>
                <p>Since time, and his predestinated end</p>
            </div></a>
    </li>
    <li><!-- ... --></li>
</ul>
                

JAVASCRIPT

该插件要做的事情是当鼠标滑过缩略图时计算出相邻区域的大小和位置。

    // list of thumbs
var $list       = $('#pe-thumbs'),
    // list's width and offset left.
    // this will be used to know the position of the description container
    listW       = $list.width(),
    listL       = $list.offset().left,
    // the images
    $elems      = $list.find('img'),
    // the description containers
    $descrp     = $list.find('div.pe-description'),
    // maxScale : maximum scale value the image will have
    // minOpacity / maxOpacity : minimum (set in the CSS) and maximum values for the image's opacity
    settings    = {
        maxScale    : 1.3,
        maxOpacity  : 0.9,
        minOpacity  : Number( $elems.css('opacity') )
    },
    init        = function() {  
        // minScale will be set in the CSS
        settings.minScale = _getScaleVal() || 1;
        // preload the images (thumbs)
        _loadImages( function() {           
            _calcDescrp();
            _initEvents();
        });
    },
    // Get Value of CSS Scale through JavaScript:
    // http://css-tricks.com/get-value-of-css-rotation-through-javascript/
    _getScaleVal= function() {
        var st = window.getComputedStyle($elems.get(0), null),
            tr = st.getPropertyValue("-webkit-transform") ||
                 st.getPropertyValue("-moz-transform") ||
                 st.getPropertyValue("-ms-transform") ||
                 st.getPropertyValue("-o-transform") ||
                 st.getPropertyValue("transform") ||
                 "fail...";
        if( tr !== 'none' ) {    
            var values = tr.split('(')[1].split(')')[0].split(','),
                a = values[0],
                b = values[1],
                c = values[2],
                d = values[3];
            return Math.sqrt( a * a + b * b ); 
        }
    },
    // calculates the style values for the description containers,
    // based on the settings variable
    _calcDescrp = function() { 
        $descrp.each( function(i) {
            var $el     = $(this),
                $img    = $el.prev(),
                img_w   = $img.width(),
                img_h   = $img.height(),
                img_n_w = settings.maxScale * img_w,
                img_n_h = settings.maxScale * img_h,
                space_t = ( img_n_h - img_h ) / 2,
                space_l = ( img_n_w - img_w ) / 2;   
            $el.data( 'space_l', space_l ).css({
                height  : settings.maxScale * $el.height(),
                top     : -space_t,
                left    : img_n_w - space_l
            });
        });
    },
    _initEvents = function() {
        $elems.on('proximity.Photo', { max: 80, throttle: 10, fireOutOfBounds : true }, function(event, proximity, distance) {   
            var $el         = $(this),
                $li         = $el.closest('li'),
                $desc       = $el.next(),
                scaleVal    = proximity * ( settings.maxScale - settings.minScale ) + settings.minScale,
                scaleExp    = 'scale(' + scaleVal + ')';
            // change the z-index of the element once 
            // it reaches the maximum scale value
            // also, show the description container
            if( scaleVal === settings.maxScale ) {  
                $li.css( 'z-index', 1000 );  
                if( $desc.offset().left + $desc.width() > listL + listW ) {    
                    $desc.css( 'left', -$desc.width() - $desc.data( 'space_l' ) );               
                }              
                $desc.fadeIn( 800 );               
            }   
            else {              
                $li.css( 'z-index', 1 );
                $desc.stop(true,true).hide();   
            }             
            $el.css({
                '-webkit-transform' : scaleExp,
                '-moz-transform'    : scaleExp,
                '-o-transform'      : scaleExp,
                '-ms-transform'     : scaleExp,
                'transform'         : scaleExp,
                'opacity'           : ( proximity * ( settings.maxOpacity - settings.minOpacity ) + settings.minOpacity )
            });
        });
    },
    _loadImages = function( callback ) {
        var loaded  = 0,
            total   = $elems.length;
        $elems.each( function(i) {     
            var $el = $(this);        
            $('').load( function() {               
                ++loaded;
                if( loaded === total )
                    callback.call();  
            }).attr( 'src', $el.attr('src') );
        });
    };
return {
    init    : init
};