4

I have a square image/graph on which the user clicks.

Is there a way to display the (x,y) coordinates of the cursor to the user in real-time whenever the user hovers over the image (user does not need to click on the image)?

oxo
  • 4,343
  • 10
  • 32
  • 35
  • 1
    Check out the following link for an answer to your question: http://www.emanueleferonato.com/2006/09/02/click-image-and-get-coordinates-with-javascript/ – Javier Sep 14 '11 at 10:44

3 Answers3

8

This should do it:

HTML

<img id="the_image" src="http://placekitten.com/200/200" />
<div id="coords"></div>

Javascript

$image = $('#the_image');
imgPos = [
    $image.offset().left,
    $image.offset().top,
    $image.offset().left + $image.outerWidth(),
    $image.offset().top + $image.outerHeight()
];

$image.mousemove(function(e){
  $('#coords').html((e.pageX-imgPos[0]) +', '+ (e.pageY-imgPos[1]));
});

DEMO (updated): http://jsfiddle.net/az8Uu/2/

Note: Throttling the mousemove handler would be a good idea too, to avoid calling the function every 4 milliseconds.

Jens Roland
  • 27,450
  • 14
  • 82
  • 104
  • I'm not a native English speaker ... What does "throttling" mean in that context ? (the definitions I've found seem irrelevant) EDIT: my bad, I found an explanation : http://remysharp.com/2010/07/21/throttling-function-calls/ – tsimbalar Sep 14 '11 at 11:15
  • 1
    I've added a link - it limits the 'rate of fire' so the event handler is only called once per N milliseconds, ie. so the coords only update 5-10 times per second instead of 250 times per second (which is just wasteful and could potentially slow down your app) – Jens Roland Sep 14 '11 at 11:18
  • 1
    @tsimbalar The idea is to call the handler only at the end of the user activity. For instance, if the user moved the mouse for a second, the mousemove handler is invoked only once at the end (instead of every 20ms during the mouse movement). – Šime Vidas Sep 14 '11 at 11:20
  • @Šime: actually what you are describing is debouncing ;) – Jens Roland Sep 14 '11 at 11:33
  • Fantastic. This is why I love SO, this is very helpful. Is there a way to have the coords displayed just "above" the cursor, in effect following the cursor around? – oxo Sep 16 '11 at 14:30
  • Sure, you can just add `$('#coords').css({left: (e.pageX-imgPos[0]), top: (e.pageY-imgPos[1])})` (make sure #coords is positioned absolutely) – Jens Roland Sep 16 '11 at 14:45
  • Ok, will have to play around with it. I said this in a comment above: This is the image I am using: i.imgur.com/bhvpy.png - I see that the coords are taken from the height/width of the image, and every coordinate is incremented by a pixel. Is there a way to "normalize" this such as to use a scale of 0-10, with 0.10 increments on both the x and y axes, regardless of image size? – oxo Sep 16 '11 at 15:35
7

Here you go:

HTML:

<img class="coords" src="http://i.imgur.com/bhvpy.png">

JavaScript:

var tooltip = $( '<div id="tooltip">' ).appendTo( 'body' )[0];

$( '.coords' ).
    each(function () {
        var pos = $( this ).position(),
            top = pos.top,
            left = pos.left,
            width = $( this ).width(),
            height = $( this ).height();

        $( this ).
            mousemove(function ( e ) {
                var x, y;

                x = ( ( e.clientX - left ) / width ).toFixed( 1 ),
                y = ( ( height - ( e.clientY - top ) ) / height ).toFixed( 1 );

                $( tooltip ).text( x + ', ' + y ).css({
                    left: e.clientX - 30,
                    top: e.clientY - 30
                }).show();
            }).
            mouseleave(function () {
                $( tooltip ).hide();
            }); 
    });

Live demo: http://jsfiddle.net/pSVXz/12/

With my updated code, you can have multiple images with this functionality - just add the class "coords" to the images.

Note: This code has to be inside the load handler (instead of the ready) handler, because we have to read the image's dimensions which we can only do for fully loaded images.

Šime Vidas
  • 182,163
  • 62
  • 281
  • 385
  • Thank you very much. Is there a way to have the coords displayed just "above" the cursor, in effect following the cursor around? – oxo Sep 16 '11 at 14:30
  • Appreciate it. This is the image I am using: http://i.imgur.com/bhvpy.png - I see that the coords are taken from the height/width of the image, and every coordinate is incremented by a pixel. Is there a way to "normalize" this such as to use a scale of 0-10, with 0.1 increments on both the x and y axes, regardless of image size? – oxo Sep 16 '11 at 15:16
2

Depending on your requirements, something based on :

$("img").mousemove(function(e) {
    console.log(e.layerX + ", " + e.layerY);
});
cloakedninjas
  • 4,007
  • 2
  • 31
  • 45
  • Based on comments - have changed pageX/pageY to layerX / layerY - which does not require you to remove offset() – cloakedninjas Sep 14 '11 at 11:21
  • Sadly, layerX / layerY are not likely to work cross-browser at all - Quirksmode doesn't include them in their compatibility table (http://www.quirksmode.org/dom/w3c_cssom.html#mousepos), jQuery specifically does not normalize it (http://api.jquery.com/category/events/event-object/) and others have mentioned issues with it here on SO (http://stackoverflow.com/questions/3343384/mouse-position-cross-browser-compatibility-javascript) – Jens Roland Sep 14 '11 at 13:00