(function( $, undefined ) { /* * hoverdir object. */ $.hoverdir = function( options, element ) { this.$el = $( element ); this._init( options ); }; $.hoverdir.defaults = { hoverdelay : 0, reverse : false }; $.hoverdir.prototype = { _init : function( options ) { this.options = $.extend( true, {}, $.hoverdir.defaults, options ); // load the events this._loadevents(); }, _loadevents : function() { var _self = this; this.$el.on( 'mouseenter.hoverdir, mouseleave.hoverdir', function( event ) { var $el = $(this), evtype = event.type, $hoverelem = $el.find( 'div' ), direction = _self._getdir( $el, { x : event.pagex, y : event.pagey } ), hoverclasses= _self._getclasses( direction ); $hoverelem.removeclass(); if( evtype === 'mouseenter' ) { $hoverelem.hide().addclass( hoverclasses.from ); cleartimeout( _self.tmhover ); _self.tmhover = settimeout( function() { $hoverelem.show( 0, function() { $(this).addclass( 'da-animate' ).addclass( hoverclasses.to ); } ); }, _self.options.hoverdelay ); } else { $hoverelem.addclass( 'da-animate' ); cleartimeout( _self.tmhover ); $hoverelem.addclass( hoverclasses.from ); } } ); }, // credits : http://stackoverflow.com/a/3647634 _getdir : function( $el, coordinates ) { /** the width and height of the current div **/ var w = $el.width(), h = $el.height(), /** calculate the x and y to get an angle to the center of the div from that x and y. **/ /** gets the x value relative to the center of the div and "normalize" it **/ x = ( coordinates.x - $el.offset().left - ( w/2 )) * ( w > h ? ( h/w ) : 1 ), y = ( coordinates.y - $el.offset().top - ( h/2 )) * ( h > w ? ( w/h ) : 1 ), /** the angle and the direction from where the mouse came in/went out clockwise (trbl=0123);**/ /** first calculate the angle of the point, add 180 deg to get rid of the negative values divide by 90 to get the quadrant add 3 and do a modulo by 4 to shift the quadrants to a proper clockwise trbl (top/right/bottom/left) **/ direction = math.round( ( ( ( math.atan2(y, x) * (180 / math.pi) ) + 180 ) / 90 ) + 3 ) % 4; return direction; }, _getclasses : function( direction ) { var fromclass, toclass; switch( direction ) { case 0: // from top ( !this.options.reverse ) ? fromclass = 'da-slidefromtop' : fromclass = 'da-slidefrombottom'; toclass = 'da-slidetop'; break; case 1: // from right ( !this.options.reverse ) ? fromclass = 'da-slidefromright' : fromclass = 'da-slidefromleft'; toclass = 'da-slideleft'; break; case 2: // from bottom ( !this.options.reverse ) ? fromclass = 'da-slidefrombottom' : fromclass = 'da-slidefromtop'; toclass = 'da-slidetop'; break; case 3: // from left ( !this.options.reverse ) ? fromclass = 'da-slidefromleft' : fromclass = 'da-slidefromright'; toclass = 'da-slideleft'; break; }; return { from : fromclass, to: toclass }; } }; var logerror = function( message ) { if ( this.console ) { console.error( message ); } }; $.fn.hoverdir = function( options ) { if ( typeof options === 'string' ) { var args = array.prototype.slice.call( arguments, 1 ); this.each(function() { var instance = $.data( this, 'hoverdir' ); if ( !instance ) { logerror( "cannot call methods on hoverdir prior to initialization; " + "attempted to call method '" + options + "'" ); return; } if ( !$.isfunction( instance[options] ) || options.charat(0) === "_" ) { logerror( "no such method '" + options + "' for hoverdir instance" ); return; } instance[ options ].apply( instance, args ); }); } else { this.each(function() { var instance = $.data( this, 'hoverdir' ); if ( !instance ) { $.data( this, 'hoverdir', new $.hoverdir( options, this ) ); } }); } return this; }; })( jquery );