这是一款jQuery和css3鼠标滑过、鼠标离开、鼠标点击圆形图片的图片特效插件。在a元素上使用:hover伪元素来制作鼠标滑过、鼠标点击等效果是一个网站最常使用的方法。但是有一个非常头疼的问题,如果引入了border-radius属性,某些区域在鼠标滑过时将不可见,特别是设置border-radius为50%的时候(圆形)。这个插件就是为解决这类问题而制作的。

HTML

html结构如下:


    

Hovered

CSS

将它做成圆形图片,样式如下:

.ec-circle{
    width: 420px;
    height: 420px;
    -webkit-border-radius: 210px;
    -moz-border-radius: 210px;
    border-radius: 50%;
    text-align: center;
    overflow: hidden;
    font-family:'Kelly Slab', Georgia, serif;
    background: #dda994 url(../images/1.jpg) no-repeat center center;
    box-shadow: 
        inset 0 0 1px 230px rgba(0,0,0,0.6),
        inset 0 0 0 7px #d5ad94;
    transition: box-shadow 400ms ease-in-out;
    display: block;
    outline: none;
}
                

现在定义一个鼠标滑过样式,但是这里不适用:hover伪元素。这里使用jQuery来切换鼠标滑过的样式。

.ec-circle-hover{
    box-shadow: 
        inset 0 0 0 0 rgba(0,0,0,0.6),
        inset 0 0 0 20px #c18167,
        0 0 10px rgba(0,0,0,0.3);
}
                

如果浏览器不支持javascript,我们定义还是使用伪元素,这个class可以在noscript.css中找到:

.ec-circle:hover{
    box-shadow: 
        inset 0 0 0 0 rgba(0,0,0,0.6),
        inset 0 0 0 20px #c18167,
        0 0 10px rgba(0,0,0,0.3);
}
                

JAVASCRIPT

我们将使插件中的所有事件仅仅应用于圆形图片上:

$.CircleEventManager            = function( options, element ) {
    this.$el            = $( element );
    this._init( options ); 
};
$.CircleEventManager.defaults   = {
    onMouseEnter    : function() { return false },
    onMouseLeave    : function() { return false },
    onClick         : function() { return false }
};
$.CircleEventManager.prototype  = {
    _init               : function( options ) {  
        this.options        = $.extend( true, {}, $.CircleEventManager.defaults, options ); 
        // set the default cursor on the element
        this.$el.css( 'cursor', 'default' );
        
        this._initEvents();      
    },
    _initEvents         : function() { 
        var _self   = this;      
        this.$el.on({
            'mouseenter.circlemouse'    : function( event ) {             
                var el  = $(event.target),               
                          circleWidth   = el.outerWidth( true ),
                          circleHeight  = el.outerHeight( true ),
                          circleLeft    = el.offset().left,
                          circleTop     = el.offset().top,
                          circlePos     = {
                              x     : circleLeft + circleWidth / 2,
                              y     : circleTop + circleHeight / 2,
                              radius: circleWidth / 2
                          };               
                // save cursor type
                var cursor  = 'default';               
                if( _self.$el.css('cursor') === 'pointer' || _self.$el.is('a') )
                    cursor = 'pointer';
                    
                el.data( 'cursor', cursor );                
                el.on( 'mousemove.circlemouse', function( event ) {
                    var distance    = Math.sqrt( Math.pow( event.pageX - circlePos.x, 2 ) + Math.pow( event.pageY - circlePos.y, 2 ) );    
                    if( !Modernizr.borderradius ) {                   
                        // inside element / circle
                        el.css( 'cursor', el.data('cursor') ).data( 'inside', true );
                        _self.options.onMouseEnter( _self.$el );                    
                    }
                    else {                  
                        if( distance  circlePos.radius && el.data('inside') ) {
                            
                            // inside element / outside circle
                            el.css( 'cursor', 'default' ).data( 'inside', false );
                            _self.options.onMouseLeave( _self.$el );                        
                        }
                    }
                });   
            },
            'mouseleave.circlemouse'    : function( event ) {
                
                var el  = $(event.target);
    
                el.off('mousemove');
                
                if( el.data( 'inside' ) ) {
                
                    el.data( 'inside', false );
                    _self.options.onMouseLeave( _self.$el );
                } 
            },
            'click.circlemouse'         : function( event ) {  
                // allow the click only when inside the circle
                var el  = $(event.target);
                if( !el.data( 'inside' ) )
                    return false;
                else
                    _self.options.onClick( _self.$el ); 
            }
        });   
    },
    destroy             : function() {  
        this.$el.unbind('.circlemouse').removeData('inside').removeData('cursor');
    }
};
                

当鼠标进入正方形的图片区域,我们为元素绑定“mousemove”事件,这样我们就能跟踪鼠标离圆心的距离,如果这个距离大于圆形的半径,我们就知道鼠标还没有滑过圆形图片,如下图:

jquery鼠标滑过圆形图片示意图

当检测到距离小于圆形的半径,我们为其绑定“mouseenter”事件。

调用插件的方法:

$('#circle').circlemouse({
    onMouseEnter    : function( el ) {
        el.addClass('ec-circle-hover');
    },
    onMouseLeave    : function( el ) {  
        el.removeClass('ec-circle-hover');   
    },
    onClick         : function( el ) {     
        alert('clicked');      
    }
});