16

Yet another question that has been pecking away at me the last few days. As you may have seen from my other questions I am creating some mind map software. So (extremely simplified) I have a two divs. One that is a square on the page, and another inside that div which is about 10 times as large and draggable. This is so that objects can be placed on the screen and then moved slightly to the side whilst another object is added etc. I do this by creating the outer div scrollable.

The problems that I am having though are to do with the mouse position in java script. If I get the mouse position anywhere in the div it wont be correct as I offset the inner div by half its size to the top and left (so effectively the user is looking at the middle of the canvas and can go any way they like). I have tried tens of different mouse coordinate functions but none of these seem to work. An example that is supposed to be cross browser that I found somewhere on the web is:

function getMouse(e) {
  var posx;
  var posy;
  if (!e) var e = window.event;
  if (e.pageX || e.pageY) {
    posx = e.pageX;
    posy = e.pageY;
  }
  else if (e.clientX || e.clientY) {
    posx = e.clientX + document.body.scrollLeft + document.getElementById("canvas").scrollLeft;
    posy = e.clientY + document.body.scrollTop  + document.getElementById("canvas").scrollTop;
  }
} //getMouse

But even this doesn't work. I am almost certain that the error is because I have the inner div being draggable. Hopefully I have made some sense trying to explain, but if I have not here is a very simple jsfiddle in an attempt to demonstrate the situation that I have (although no mouse clicking is done here, purely to demonstrate my div structure). In the product I am making the user will double click on the canvas and a new object will appear, and hence why the mouse co-ordinates need to be correct.

I hope someone out there can help me.

Thanks in advance.

EDIT: Failed to mention that for part of my application I use JQuery so a solution either with or without JQuery would be fine. Thanks again.

Adam Holmes
  • 1,693
  • 3
  • 20
  • 32
  • I noticed that your Fiddle is using jQuery. Since you didn't mention it here, will you be using jQuery as part of your solution? What mouse coordinates are you expecting, relative to the canvas or the document? – Nimrod Feb 11 '11 at 00:10
  • Well if it can be done easier in JQuery then thats ok... Either solution is fine... I will update post though. I need the position relative to the inner div, i.e. #canvas in the jsfiddle. Thanks. – Adam Holmes Feb 11 '11 at 00:16

2 Answers2

23

I hope I understood your problem correctly.

You can use .offset() to determine the current offset of any element relative to the root document. This offset can be then compared with the mouse position.

You can use event.pageX and event.pageY to determine the current mouse position.

You can use ${document}.scrollLeft() and ${document}.scrollTop() to determine the current scroll position.

The mouse position relative to the inner div can then be obtained with

$("#outer_canvas").mousemove(function(e) {
    var relativePosition = {
      left: e.pageX - $(document).scrollLeft() - $('#canvas').offset().left,
      top : e.pageY - $(document).scrollTop() - $('#canvas').offset().top
    };
    $('#mousepos').html('<p>x: ' + relativePosition.left + ' y: ' + relativePosition.top + ' </p>');
});
Aleksi Yrttiaho
  • 7,436
  • 24
  • 35
4

I know this is very late, but I ran into the same situation myself and this is how I tackled it.

I didn't want to use jQuery so I wrote this recursive offset function to handle a problem with scroll offsets and placement of a div for example in multiple scrollable divs.

function recursive_offset (aobj) {
 var currOffset = {
   x: 0,
   y: 0
 } 
 var newOffset = {
     x: 0,
     y: 0
 }    

 if (aobj !== null) {

   if (aobj.scrollLeft) { 
     currOffset.x = aobj.scrollLeft;
   }

   if (aobj.scrollTop) { 
     currOffset.y = aobj.scrollTop;
   } 

   if (aobj.offsetLeft) { 
     currOffset.x -= aobj.offsetLeft;
   }

   if (aobj.offsetTop) { 
     currOffset.y -= aobj.offsetTop;
   }

   if (aobj.parentNode !== undefined) { 
      newOffset = recursive_offset(aobj.parentNode);   
   }

   currOffset.x = currOffset.x + newOffset.x;
   currOffset.y = currOffset.y + newOffset.y; 
   console.log (aobj.id+' x'+currOffset.x+' y'+currOffset.y); 
 }
 return currOffset;
}

Using it for real:

    var offsetpos = recursive_offset (this); //or some other element

    posX = event.clientX+offsetpos.x;
    posY = event.clientY+offsetpos.y;