Search code examples
jqueryincrementmousemovemouseentermouseleave

jQuery number increment/decrement by pixel movement, using mouseenter and mousemove


I have this jQuery. The code gets the coordinates where the mouse enters, offset to start at 0:

var inc_X_by = 0, inc_Y_by = 0, total_X = 0, total_Y = 0;

$( "#mouse_over" ).mouseenter(function() {
  var $this = $(this),
      offset = $this.offset(),
      in_X = (event.clientX - offset.left),
      in_Y = (event.clientY - offset.top);

then gets the coordinates as the mouse moves inside:

  $('#mouse_over').mousemove(function(e){
    var mouse_X = (event.clientX - offset.left),
        mouse_Y = (event.clientY - offset.top);

and gives a total increment + or - the difference:

    inc_X_by =  mouse_X - in_X;
    inc_Y_by =  mouse_Y - in_Y;    
  });

Then when the mouse leaves the div it adds the increment/decrement to a total each time:

}).mouseleave(function() {
  total_X = total_X + inc_X_by;
  total_Y = total_Y + inc_Y_by;
});

Here is the working jsfiddle

At the moment the total of all increments only updates when the mouse leaves the div. However I want it to update continuously as the mouse moves inside. If I drop the totals calculations into the mousemove function it adds the inc number EVERY single time it changes, ie: if the inc goes up by two pixels, from 100 to 102, instead of adding 2 it adds 100, 101, 102 = 303. A big difference.

Anyone know a solution?

As a noob any other advice on the code is greatly appreciated too.


Solution

  • I fixed this by adding a new var:

    var X_prev = 0, Y_prev = 0;
    

    and then an if/else statement that determines if the mouse is moving l/r, h/v

    if (X_prev < mouse_X) { 
        inc_X_by = 1;
      } else if (X_prev == mouse_X) {
        inc_X_by = 0;
      } else {
        inc_X_by = -1;
      };
    

    then set prev mouse position to current.

    X_prev = mouse_X;
    

    so if, for example, previous mouse position is less than current, then mouse is moving right, set increment to +1. Then by moving the totals into mousemove, it adds +1 each time it fires. Then there's no need for mouseenter or mouseleave.

    The complete code looks like this, jsfiddle here:

    var inc_X_by = 0, inc_Y_by = 0, total_X = 0, total_Y = 0, X_prev = 0, Y_prev = 0;
    
    $('#mouse_over').mousemove(function(e){
        var $this = $(this),
            offset = $this.offset(),
            mouse_X = (event.clientX - offset.left),
            mouse_Y = (event.clientY - offset.top);
    
          if (X_prev < mouse_X) { 
              inc_X_by = 1;
          } else if (X_prev == mouse_X) {
              inc_X_by = 0;
          } else {
              inc_X_by = -1;
          };
    
          if (Y_prev < mouse_Y) { 
              inc_Y_by = 1;
          } else if (Y_prev == mouse_Y) {
              inc_Y_by = 0;
          } else {
              inc_Y_by = -1;
          }
    
          X_prev = mouse_X;
          Y_prev = mouse_Y;
    
          total_X = total_X + inc_X_by;
          total_Y = total_Y + inc_Y_by;
        });
    })
    

    One major difference is that if the mouse skips over very quickly then mousemove only fires a couple of times, therefore you will only increment by a few, when in fact you may have travelled much more.