0

I'm trying to create a game and the goal currently is do draw a line (narrow div) from player position to mouse hovering position, so that the line displays the trajectory of ability, like in diablo games or modern moba's, but only when left click is held down.

Currently I listen for mouse down and mouse up and add or remove classes when I need to. But now I need to make it so that while the left click is pressed, I need to get mousemove coordinates.

My code assigns mouse move listener when the left click is down, but I can't remove the mousemove listener when the left click is up

function detectLeftButton(event) {
    if (event.metaKey || event.ctrlKey || event.altKey || event.shiftKey) {
        return false;
    } else if ('buttons' in event) {
        return event.buttons === 1;
    } else if ('which' in event) {
        return event.which === 1;
    } else {
        return (event.button === 1 || event.type === 'click');
}


  try {
    map.addEventListener('mousedown', (event) => {

    if (detectLeftButton(event) === true) {
      handleMouseDown();
      map.onmousemove = handleMouseMove();

      map.addEventListener('mouseup', () => {
        handleMouseUp();
        map.onmousemove = null;
    
      });
    }
   })
  }
  catch(err) {
    
  }

1 Answer 1

1

Although I'm not 100% sure why setting onmousemove to null doesn't work, I can say that you can use removeEventListener in order to detach an event handler from the event. For this to work, you have to pass a reference to the function you're trying to remove to both addEventListener and removeEventListener. Also, the way you've written the code, you're not clearing your mouseUp event handler, which means it may end up getting invoked more times than you want.

Inside the try/catch block take this for a spin:

map.addEventListener('mousedown', (event) => {
    if (detectLeftButton(event) === true) {
      handleMouseDown();
      map.addEventListener('mousemove', handleMouseMove);
  }
})

map.addEventListener('mouseup', (event) => {
   handleMouseUp();
   map.removeEventListener('mousemove', handleMouseMove);
})

Another option would be to have some kind of state variable that you set in mousedown/mouseup that allows a mouse move handler to determine whether or not to take action. Then you may not need to worry about detaching the event (although I don't know enough about your solution to say for sure). You can find an example of this type of solution on MDN: https://developer.mozilla.org/en-US/docs/Web/API/Element/mousemove_event

Sign up to request clarification or add additional context in comments.

2 Comments

thanks a lot, this actually worked, could you please explain, why no brackets on function declaration when adding event listener? as in handleMouseMove instead of handleMouseMove(e)?
When you use parentheses you are invoking the function and assigning its result. When you omit the parentheses you are passing a reference to the function; anyone who has the reference can then invoke the function. In JavaScript functions are first class types, and you can think of function names just as you do variable names. In this case you pass a reference to handleMouseMove, and the browser takes care of calling it with the correct value of e when the mousemove event fires.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.