How to Make a Hover-and-Click
Trigger for Circular Web Elements with jQuery
by: Carmela
Ever tried designing a circular web element and learn web design that ends up
being clickable even outside its area? Frustrating, isn’t it? Yet if you use
square or rectangular element, the overall web design suffers.
So web designer and developer Manoela Ilic aka. Mary Lou has developed
a hover-and-click trigger for circular web elements using jQuery. This was to
address the problem of the hover event occurring within the square area a
circular element is placed in, when hovering and clicking should only happen
within the circle itself.
Here’s the demo to
illustrate the issue and for you to see the effect after you apply Mary Lou’s
plugin code.
This is how the code works:
First you’ll create a structure like so:
<a href="#" id="circle" class="ec-circle">
|
||
<h3>Hovered</h3>
|
</a>
|
And this will be its style:
.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; |
} |
.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); |
||
} |
Disable your Javascript first, then add your
pseudo-class. You can find this script
in 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 Code
This simple plugin that basically redefines the ‘mousenter,’
‘mouseleave,’ and ‘click’ events so that
they only come into effect when you hover on your circular shape:
$.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 / 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');
|
|||
|
|||
}
|
||
};
|
||
The idea is that when
you enter the square bounding box or square perimeter around your circular
element, you bind the ‘mousemove’ event to the shape. This way you can track
the distance of the mouse to the center of the circle. If the distance is longer than the radius,
then no hovering occurs.
Your mouse only stars hovering when it enters the radial
area of your circular element. This triggers the ‘mouseenter’ event. Also, this
is the only time when you can click on the element, triggering the ‘click’
event.
When you apply this plugin to your circle, you add the hover
class on ‘mouseenter’ and remove it on ‘mouseleave’.
$('#circle').circlemouse({
|
||
onMouseEnter
: function( el ) {
|
||
|
||
el.addClass('ec-circle-hover');
|
|
||
},
|
onMouseLeave
: function( el ) {
|
||
|
el.removeClass('ec-circle-hover');
|
||
|
},
|
||
onClick
: function( el ) {
|
|
||
alert('clicked');
|
|
||
}
|
});
|
The regular pseudo :hover class is also defined in the
noscript.css. This is applied when JavaScript is disabled. You can also
download the plugin HERE.
Give this plugin a try and let us know how it works out for
you. Good luck!
Demo image is from Andrew & Lili, licensed under
the Attribution-NonCommercial
3.0 Unported (CC BY-NC 3.0) License.
No comments:
Post a Comment