neoDev
neoDev

Reputation: 3049

jquery mouse selection not working properly

I am trying to create a mouse selection using jQuery, this is what I am trying, it works but there is a bug: if I start the selection and move the mouse in circle, the selection breaks... How can I solve it?

Fiddle

distanceStart = 0;
distanceEnd = 0;
mousedown = false;

$(window).on('mousedown',function(e){
    e.preventDefault();
    mousedown = true;
    distanceXStart = e.clientX;
    distanceYStart = e.clientY;
    $div = $('<div/>', {
        class: 'class'
    }).appendTo('body');
});

$(window).on('mouseup',function(e){
    e.preventDefault();
    mousedown = false;
    $div.remove();
});

$(window).on('mousemove',function(e){
    e.preventDefault();
    if(mousedown){
        distanceXEnd = e.clientX;
        distanceYEnd = e.clientY;
        distanceX = (distanceXEnd - distanceXStart);
        distanceY = (distanceYEnd - distanceYStart);
        if(distanceX > 0 && distanceY > 0){
            $div.css({
                'left': (e.clientX - (distanceX/*/2*/)),
                'top': (e.clientY - (distanceY/*/2*/)),
                'width': distanceX,
                'height': distanceY
            });
        }else
        if(distanceX < 0 && distanceY < 0){
            $div.css({
                'left': e.clientX,
                'top': e.clientY,
                'width': (1-distanceX),
                'height': (1-distanceY)
            });
        }
    }
});

Upvotes: 1

Views: 60

Answers (2)

Razzi Abuissa
Razzi Abuissa

Reputation: 4112

You can accomplish this type of interactivity with HTML5 canvas. https://jsfiddle.net/nbwLr27s/1/

Canvas is nice for this sort of thing since it gives you full control over the shapes you'd like to display and performs very well since there's no DOM manipulation involved.

With canvas fillRect, all you need is the start x, start y, width and height. I used the following code:

  var leftmost = Math.min(start_x, coords.x)
  var rightmost = Math.max(start_x, coords.x)
  var lowest = Math.min(start_y, coords.y)
  var highest = Math.max(start_y, coords.y)
  ctx.fillRect(leftmost, lowest, rightmost - leftmost, highest - lowest)

Upvotes: 2

Deryck
Deryck

Reputation: 7658

You were almost there, you just forgot the other two conditions to check on: distanceX < 0 OR distanceY < 0

Here's a demo using your original fiddle

And here's what I added just after that second else if ends:

// ... stuff
else if ( distanceX < 0 ) {
    $div.css({
        'left': e.clientX,
        'top': e.clientY - distanceY,
        'width': (1 - distanceX),
        'height': distanceY
    });
}
else if ( distanceY < 0 ) {
    $div.css({
        'left': e.clientX - distanceX,
        'top': e.clientY,
        'width': distanceX,
        'height': (1 - distanceY)
    });
}

Upvotes: 2

Related Questions