19

I'm writing an HTML5 canvas drawing app, and I need to be able to tell whether or not the left mouse button is pressed down during a mousemove event. On Chrome, this works:

if (event.which == 1) { <do stuff> }

But in FireFox, event.which always is 1, no matter whether or not the button is pressed.

How can I detect whether the mouse button is pressed during a mousemove event?

dieki
  • 2,435
  • 5
  • 23
  • 29
  • try what you want to do with in onmousedown event not in the onmousemove event :) – Marwan Oct 29 '11 at 12:30
  • 2
    Well, I currently have a solution where I set a variable (is_drawing) to true on the mousedown event and then set it to false on the mouseup/mouseout event. But I don't like this 'cause if the mouse leaves the canvas and then comes back, the drawing doesn't restart until you click again. So a real solution would be a real help. – dieki Oct 29 '11 at 12:32

4 Answers4

12

In short, you can't. MDN, for example, explains:

When a mouse button event occurs, a number of additional properties are available to determine which mouse buttons were pressed and the location of the mouse pointer. The event's button property can be used to determine which button was pressed, where possible values are 0 for the left button, 1 for the middle button and 2 for the right button. If you've configured your mouse differently, these values may be different.

...

The button and detail properties only apply to the mouse button related events, not mouse movement events. For the mousemove event, for example, both properties will be set to 0.

If you want, you can set global mousedown and mouseup handlers that set flags appropriately and then at any given point in time you can with relative degree of accuracy determine if/which mouse button is pressed.

davin
  • 44,863
  • 9
  • 78
  • 78
7

You should use a variable to hold the state of the mousedown. When you mousedown on the canvas set it to true, and when you mouseup on the document set it to false..

This way it will be cleared wherever you click..

Something like this

var isMouseDown = false;

var draw = document.getElementById('draw');

document.addEventListener('mouseup',
                          function(){
                              isMouseDown = false;
                          },
                          false);

draw.addEventListener('mousedown',
                      function(e){
                          e.preventDefault(); // cancel element drag..
                          isMouseDown = true;
                      },
                      false);

draw.addEventListener('mousemove',
                      function(e){
                          if (isMouseDown){
                              // do the drawing ..
                          }
                      },
                      false);

Demo at http://jsfiddle.net/gaby/8JbaX/

Gabriele Petrioli
  • 191,379
  • 34
  • 261
  • 317
  • Right, this is what I'm currently doing. I had hoped for a better solution, but if this is all I can do, I guess it is. :P – dieki Oct 29 '11 at 12:54
2

Actually, you can check event.buttons on Firefox which tells you if left button, right button or none are pressed. You will need an if-statement to differentiate with Chrome which doesn't have event.buttons.

jacklehamster
  • 311
  • 3
  • 6
0

I use this pseudo-polyfill to avoid FireFox mouseMove problems:

function fixWhich(e) {
    if (!e.which && e.button) { // if no which, but button (IE8-)
        if (e.button & 1)
            e.which = 1; // left
        else if (e.button & 4)
            e.which = 2; // middle
        else if (e.button & 2)
            e.which = 3; // right

    }
    if (e.buttons) { //if there's buttons, i set new option buttondown (FF)
        if (e.buttons & 1)
            e.buttondown = 1; // left
        else if (e.buttons & 4)
            e.buttondown = 2; // middle
        else if (e.buttons & 2)
            e.buttondown = 3; // right

    }
}

I call it "pseudo" because, it forces me to check the button down while moving this way:

if (e.buttondown === 1) {
        //do anything
    }

Instead of normal:

if (e.which === 1) {
       //do anything
    }