0

How to resolve X Y coords for any canvas in Firefox. I'm using clientX vs layerX in Firefox. For some reason layerX is not working.

   $("#circle").click(function(e) {

        painter.brush = function(e) {
            var shape = Circle(e.clientX, e.clientY, 0, paper);
            shapes.push(shape);

            $paper.bind('mousemove', function(e) {
                shape.updateEnd(e.clientX, e.clientY);
            });
        };

        $paper.bind('mouseup', function(e) {
            var shape = shapes.pop();             
            $(this).unbind('mousemove');
        });

        $paper.bind('mousedown', function(e) {
            painter.brush.call(this, e);
        });

    });
uiuxhub
  • 1,209
  • 2
  • 14
  • 24

2 Answers2

1

e.clientX, e.clientY reports coordinates relative to the document client window, not relative to the canvas.

Therefore you must account for the canvas's position on the document. You can use .getBoundingClientRect to get the position of the canvas relative to the document.

function handleMouseMove(e){
    BB=canvas.getBoundingClientRect();
    mouseX=parseInt(e.clientX-BB.left);
    mouseY=parseInt(e.clientY-BB.top);
}
markE
  • 102,905
  • 11
  • 164
  • 176
1

Mozilla notes this about layerX/layerY on their site:

Non-standard
This feature is non-standard and is not on a standards track. Do not use it on production sites facing the Web: it will not work for every user. There may also be large incompatibilities between implementations and the behavior may change in the future.

In other words, try to stay clear of using these properties - it will just make problems for you as they won't work for everyone.

The more appropriate approach today is to use getBoundingClientRect() which is relative to the client window, aka viewport as the name suggest (speaking of which, document, page, client can be confusing, see this to get an overview).

It will take scrolling into account (source):

The amount of scrolling that has been done of the viewport area (or any other scrollable element) is taken into account when computing the bounding rectangle.

But in order to compensate for the difference between the element's position and the mouse position we simply subtract the element's position from the mouse coordinates:

var rect = el.getBoundingClientRect();
var x = e.clientX - rect.left;
var y = e.clientY - rect.top;

Now you will have correct position relative to canvas. There are a couple of caveats though:

  • border thickness is not accounted for
  • padding is not accounted for

There are a simple trick you can use if you need border and/or padding, and that is to insert the canvas element inside a div. Apply padding/border on the div element instead.

Or you can calculate the border/padding thickness using getComputedStyle for the element (left and top only), and then subtract those from the position as well.