jQuery drag and draw

Andrew picture Andrew · Jan 16, 2012 · Viewed 10.3k times · Source

I'm trying to build a jQuery plugin that allows you to drag and draw a rectangle (or a div with a border) but I'm not sure how to do it. I don't know of any that currently have this ability so I don't know where to look for an example of how to do this.

How can I implement drag and draw in jQuery?

Answer

Peter-Paul van Gemerden picture Peter-Paul van Gemerden · Jan 16, 2012

The basics for something like this are quite simple, when you think about it:

  • Listen for mousedown events on some container (possible the entire document);
    • Place an absolutely positioned element at the position of the mouse, using the mouse coordinates from the event object (e.pageX and e.pageY);
    • Start listening to mousemove events to change the width and height object (based on the mouse coordinates);
  • Listen for the mouseup event to detach the mousemove event listener.

The aforementioned absolute placed element is, e.g., a <div> with a border and background: transparent.

Update: here is an example:

$(function() {
    var $container = $('#container');
    var $selection = $('<div>').addClass('selection-box');

    $container.on('mousedown', function(e) {
        var click_y = e.pageY;
        var click_x = e.pageX;

        $selection.css({
          'top':    click_y,
          'left':   click_x,
          'width':  0,
          'height': 0
        });
        $selection.appendTo($container);

        $container.on('mousemove', function(e) {
            var move_x = e.pageX,
                move_y = e.pageY,
                width  = Math.abs(move_x - click_x),
                height = Math.abs(move_y - click_y),
                new_x, new_y;

            new_x = (move_x < click_x) ? (click_x - width) : click_x;
            new_y = (move_y < click_y) ? (click_y - height) : click_y;

            $selection.css({
              'width': width,
              'height': height,
              'top': new_y,
              'left': new_x
            });
        }).on('mouseup', function(e) {
            $container.off('mousemove');
            $selection.remove();
        });
    });
});

Demo: http://jsbin.com/ireqix/226/