0

I have tried to draw an image in my canvas then try to click inside the image with the mouse. But the X and Y positions are not correct, i took offset's into consideration and corrected for that but they are still incorrect.

I currently don't know how else to solve it. I have made a fiddle to replicate the situation including the parent div the canvas resides inside of.

http://jsfiddle.net/bX5Dr/8/

The code i used to take offset into consideration, which appears not to be working:

function getxy(event,el){
    canvasX = event.pageX - el.offsetLeft,
    canvasY = event.pageY - el.offsetTop;
    return {x:canvasX, y:canvasY}
 //does not give the same answer as you would expect when using drawImage();
}

In the fiddle the top left corner of the canvas should be 0,0 but it is not according to my calculation i used.

SheetJS
  • 22,470
  • 12
  • 65
  • 75
Sir
  • 8,135
  • 17
  • 83
  • 146
  • tried removing the margin and border pixels in the calculation? –  Jul 30 '13 at 05:34
  • I have not - i thought offset took that into consideration =/ how would i incorporate them ? – Sir Jul 30 '13 at 05:35
  • Your element offsetLeft is always 0 since you're applying the margin-left to it's parent... change it to: `canvasX = event.pageX - el.parentNode.offsetLeft,` http://jsfiddle.net/bX5Dr/9/ – JayMoretti Jul 30 '13 at 05:41
  • Ah i see, what if there is a bunch of divs higher up in the hierarchy. For example in my site theres a few grandparent great grandparent divs etc would i have to take them all into account too ? – Sir Jul 30 '13 at 05:45

3 Answers3

2

What about using element.getBoundingClientRect(), as suggested here?

function getxy(event,el){
    var rect =  el.getBoundingClientRect();
    canvasX = event.pageX -  rect.left,
    canvasY = event.pageY - rect.top;
    return {x:canvasX, y:canvasY}
}
Community
  • 1
  • 1
Katona
  • 4,816
  • 23
  • 27
  • It works but i get floating point numbers in return. Is that normal ? – Sir Jul 30 '13 at 05:51
  • 1
    I'm inclined to give this the correct answer result solely to help others in future, as this is much more elegant solution. – Sir Jul 30 '13 at 05:54
  • indeed, [element.getBoundingClientRect()](https://developer.mozilla.org/en-US/docs/Web/API/element.getBoundingClientRect) returns a [TextRectangle](https://developer.mozilla.org/en-US/docs/XPCOM_Interface_Reference/nsIDOMClientRect), which have float properties – Katona Jul 30 '13 at 05:56
  • Note, i just noticed it gives a different answer for me if i have dev tools open =/ is there a solution for that? If i scroll down and the hover over canvas the scroll is added to it =/ how strange. – Sir Jul 30 '13 at 05:59
1

Your element offsetLeft is always 0 since you're applying the style to it's parent...

change the offset target to:

canvasX = event.pageX - el.offsetParent.offsetLeft,

http://jsfiddle.net/bX5Dr/9

For more info on calculating an object offset relative to the page, considering it's parent nodes, see: http://www.quirksmode.org/js/findpos.html

JayMoretti
  • 255
  • 1
  • 3
  • 11
0

What I meant was you can compensate for the margin-left:20px and border:1pxlike this;

canvasX = event.pageX - el.offsetLeft-21,
canvasY = event.pageY - el.offsetTop-1;

but yea , why play with the child element when others have given the solution to change the parent's offset