How to determine the direction on onmousemove event?
Asked Answered
C

3

13

On some condition I want to cancel onmousemove event when mouse goes down, for example. Is it possible to determine the direction of onmousemove event? jQ or JS is Ok.

I have drag’n’drop elements. The user drags the elenment up. If, for example, the bottom of the element reaches some position in the document (i.e. 500px from the top of the document) the onmousemove stops. And if the user will try to drag the element up again the function will not start. Only drag down will be possible for this element. So I thought it would be quite easy to do it by catching the direction of the mousemove event. But it seems there’s no such kind of standard properties.

Chaucerian answered 28/1, 2012 at 18:12 Comment(2)
What have you tried so far??Henequen
Not yet anything. I though there may be some properties of mouse events which I couldn’t find myself in W3C specification and in jQ documentation. If there’s nothing special for this purpose I’ll try to solve the task different way. But strange, it can be very useful standard property.Chaucerian
B
27

You can save the position of the last mousemove event to compare to the current position:

//setup a variable to store our last position
var last_position = {},
$output       = $('#output');

//note that `.on()` is new in jQuery 1.7 and is the same as `.bind()` in this case
$(document).on('mousemove', function (event) {

    //check to make sure there is data to compare against
    if (typeof(last_position.x) != 'undefined') {

        //get the change from last position to this position
        var deltaX = last_position.x - event.clientX,
            deltaY = last_position.y - event.clientY;

        //check which direction had the highest amplitude and then figure out direction by checking if the value is greater or less than zero
        if (Math.abs(deltaX) > Math.abs(deltaY) && deltaX > 0) {
            //left
        } else if (Math.abs(deltaX) > Math.abs(deltaY) && deltaX < 0) {
            //right
        } else if (Math.abs(deltaY) > Math.abs(deltaX) && deltaY > 0) {
            //up
        } else if (Math.abs(deltaY) > Math.abs(deltaX) && deltaY < 0) {
            //down
        }
    }

    //set the new last position to the current for next time
    last_position = {
        x : event.clientX,
        y : event.clientY
    };
});

Here is a demo: http://jsfiddle.net/Dv29e/

Update

You can also throttle the mousemove event to get more of a general idea where the mouse has moved:

var last_position = {},
    $output       = $('#output'),
    mousemove_ok  = true,
    mouse_timer   = setInterval(function () {
        mousemove_ok = true;
    }, 500);
$(document).on('mousemove', function (event) {
    if (mousemove_ok) {
        mousemove_ok = false;
        ...
    }
});

This will only check the cursor's position against it's past position if:

  1. the last position exists.
  2. the mousemove_ok variable is set to true which is done every half second.

Here is a throttled demo: http://jsfiddle.net/Dv29e/4/

Bulahbulawayo answered 28/1, 2012 at 18:21 Comment(2)
You need to take the scrolling into account.Coth
Thanks for the correction, clientX and clientY are probably more appropriate.Bulahbulawayo
S
8

There are standard properties that show deltas relevant to previous mouse move event:

document.addEventListener('mousemove', function (event) {
  directionX = event.movementX || event.mozMovementX || event.webkitMovementX || 0;
  directionY = event.movementY || event.mozMovementY || event.webkitMovementY || 0;
});

Like said in the documentation:

The MouseEvent.movementX read-only property provides the shift in the X coordinate of the mouse pointer between that event and the previous mousemove event.

Stepaniestepbrother answered 31/7, 2016 at 7:48 Comment(1)
This is nice but support list is small!Situate
P
0

event.movementX is the difference in px from the previous positionX, e.g. 100 for right movement of 100 px, -100 for left movement etc, 0 for no movement.

Palatinate answered 29/8, 2017 at 7:8 Comment(1)
great idea, but be aware that event.movementX results undefined and won't work with all mobile devicesSuppository

© 2022 - 2024 — McMap. All rights reserved.