Web designers find themselves in a tough situation - they have to build beautiful user interfaces that are intuitive and usable in the same time. Sometimes, despite our earnest efforts, web applications may become difficult to use for novice users. One solution is to create some sort of a tour of your application's features. The other is to incorporate visual cues in the design itself.

In this tutorial, we will be writing a jQuery plugin that will help you draw users' attention to a specific part of the page, in the form of a small arrow that is displayed next to their mouse cursor. This can be useful for pointing to missed form fields, buttons that need to be pressed, or validation errors that need to be scrolled into view.

How it works

Lets dive straight to the code - it comes at around 100 lines (with comments), so it is not difficult to follow.

jquery.pointpoint.js

(function($){ // Defining our jQuery plugin $.fn.pointPoint = function(prop){ // Default parameters var options = $.extend({ "class" : "pointPointArrow", "distance" : 30 },prop); var pointers = []; // If CSS transforms are not supported, exit; if(!$.support.transform){ this.destroyPointPoint = function(){}; return this; } this.each(function(){ var findMe = $(this), point = $('<div class="'+options['class']+'">').appendTo('body'), offset, center = {}, mouse = {}, props = {}, a, b, h, deg, op, pointHidden = true, rad_to_deg = 180/Math.PI; pointers.push(point); // Calculating the position of the pointer on mouse move $('html').bind('mousemove.pointPoint',function(e){ if(pointHidden){ point.show(); pointHidden = false; } offset = findMe.offset(); // The center of the element we are pointing at center.x = offset.left + findMe.outerWidth()/2; center.y = offset.top + findMe.outerHeight()/2; mouse.x = e.pageX; mouse.y = e.pageY; // We are treating the mouse position and center // point as the corners of a right triangle. // h is the hypotenuse, or distance between the two. a = mouse.y - center.y; b = center.x - mouse.x; h = Math.sqrt(a*a + b*b); // Calculating the degree (in radians), // the pointer should be rotated by: deg = Math.atan2(a,b); // Lowering the opacity of the pointer, depending // on the distance from the mouse pointer op = 1; if(h < 50){ op = 0; } else if(h < 160){ op = (h - 50) / 110; } // Moving and rotating the pointer props.marginTop = mouse.y-options.distance*Math.sin(deg); props.marginLeft = mouse.x+options.distance*Math.cos(deg); props.transform = 'rotate('+(-deg*rad_to_deg)+'deg)'; props.opacity = op; point.css(props); }).bind('mouseleave.pointPoint',function(){ point.hide(); pointHidden = true; }); }); this.destroyPointPoint = function(){ // Unbind all the event handlers // and remove() the pointers $('html').unbind('.pointPoint'); $.each(pointers,function(){ this.remove(); }); }; return this; }; })(jQuery);

When you call pointPoint(), it creates an event listener for the mousemove event. Inside it, the plugin calculates the position and rotation of the arrow using trigonometry functions. Check out this Wikipedia article if you'd like to learn more.

I am also using the transform.js CSS hooks for jQuery, which level the support for CSS3 rotations in browsers that support them (this means the plugin will not work in IE678).

How to use it

To include jQuery PointPoint in your website, you need to copy the jquery.pointpoint folder (located in /assets in the downloadable zip) in your directory structure. After this, all you need to do is include the two js files and the stylesheet, that you find inside, in your page. Refer to index.html as an example.

The plugin itself is simple to use. You just need to call it on the element which you need to point to. The plugin will automatically find the position of the element and update the arrow when you move the mouse. You can also pass an arguments object with two properties - "class" and "distance".

$('#pushButton').pointPoint(); /* // You can also pass arguments: $('#pushButton').pointPoint({ "class":"myNewPointer", "distance":100 }); */

The snippet above adds an arrow next to the mouse cursor, which points to the element with an id of "pushButton". The arguments in the second example will set a custom class on the arrow (in case you want to customize the styling) and move it further away from the mouse cursor. The default styles of the arrow are defined in jquery.pointpoint.css.

When you call the plugin, it returns a jQuery object, so you can use it inside method call chains. There is one one minor difference, however - this object has an additional method - destroyPointPoint(), which you can use to cancel the plugin:

var pp = $('#pushButton').pointPoint(); $('body').click(function(){ pp.destroyPointPoint(); });

This will remove all arrows and destroy the event listeners for the mouse move event.

We are done!

I hope you find the plugin useful and only use it for good, not evil. As usual, share your suggestions in the comments section.