user669677
user669677

Reputation:

get mouse position on canvas in Firefox

I'd like to get the X, Y coords relative to the canvas (on mouse-move event).

I'm using this:

<canvas id='c' onmousemove="xy(event)" WIDTH=500 HEIGHT=300>

js:

function xy(e)
{
    x = e.offsetX||e.layerX;
    y = e.offsetY||e.layerY;
}

This works well in Chrome but dont in Firefox. If the canvas element is in 0,0 position it works also in Firefox.

Take a look at this: http://jsbin.com/ozowaz/10

What can I do to make it working in FF too?

Upvotes: 1

Views: 3115

Answers (4)

Heinzlmaen
Heinzlmaen

Reputation: 965

@2astalavista I can't comment due to reputation, so i'll put this here, eventhough i'm not supposed to do this:

I tried the accepted answer, but it only solves the problem from other elements positioned left/above the canvas. For me it didn't take the canvas' margin into account. I don't know if i did it correctly though. Also i don't like the idea of a Html sided solution. Somebody changes the Html, forgets the "position: relative;" resulting in a bug that's almost impossible to track down.

I used Nech's solution, but noticed that it doesn't work correctly when i have elements positioned left or above the canvas. It only takes things like the canvas' margin into account.

I worked around with the following code, the Firefox part is still only about 95 - 99% accurate, compared to the Chrome part. But it gets the job done:

function getEventX(event){
    if (event.offsetX) {
        return event.offsetX;
    }
    if (event.clientX) {
        var currentElement = event.currentTarget;
        var offsetLeft = currentElement.offsetLeft;

        while(currentElement.parentElement && currentElement.parentElement.offsetLeft){
            currentElement = currentElement.parentElement;
            offsetLeft += currentElement.offsetLeft;
        }     

        return event.clientX - offsetLeft;
    }
    return null;
};

function getEventY(event){
    if (event.offsetY) {
        return event.offsetY;
    }
    if (event.clientY) {
        var currentElement = event.currentTarget;
        var offsetTop = currentElement.offsetTop;

        while(currentElement.parentElement && currentElement.parentElement.offsetTop){
            currentElement = currentElement.parentElement;
            offsetTop += currentElement.offsetTop;
        }     

        return event.clientY - offsetTop;  
    }
    return null;
};

I also removed the canvas being handed to the function, you can get the canvas with:

event.currentTarget;

Probably better when handling multiple canvases.

Upvotes: 1

Nech
Nech

Reputation: 331

This worked for me (pure js)

function getX(event, canvas){
     if(event.offsetX){
       return event.offsetX;
     }
     if(event.clientX){
     return event.clientX - canvas.offsetLeft;
     }
    return null;
 }

function getY(event, canvas){
    if(event.offsetY){//chrome and IE
        return event.offsetY;
    }
    if(event.clientY){// FF
        return event.clientY- canvas.offsetTop;
    }
    return null;    
}

Upvotes: 1

user669677
user669677

Reputation:

The container must have

position: relative;

style. Don't use that container for styling border, because it means +n px (n= boder size) in coordinates!

thanks to: http://dev.opera.com/articles/view/html5-canvas-painting/

Upvotes: 4

DerWaldschrat
DerWaldschrat

Reputation: 1915

You could try to compute it:

// ...
var x = e.pageX - canvas.offsetTop;

where canvas is the canvas dom element. That should work in FF.

Upvotes: 1

Related Questions