Search code examples
javascriptgoogle-chrome-extensionhtml5-canvasimgur

Getting elements from selected area in Javascript


I need to implement getting elements from selected area in Javascript. This is needed to make a better, desktop-like UI in chrome app. The nearest example is selecting area in Imgur extension:

screenshot

So the question is:

  1. How this selecting can be done in javascript?
  2. How to get elements from this selection?

Solution

  • I found this interesting so I made something from scratch, using jQuery because it would become too complicated otherwise: http://jsfiddle.net/EuSBU/1/.

    I hope it's straight-forward enough to follow, please ask if there is something you want to know.

    It basically comes down to checking for each element whether the rectangle is encapsulating it.

    $("#start_select").click(function() {
        $("#select_canvas").show();
    });
    
    $('*').bind('selectstart', false);
    
    var start = null;
    var ctx = $("#select_canvas").get(0).getContext('2d');
    ctx.globalAlpha = 0.5;
    
    $("#select_canvas").mousedown(function(e) {
        start = [e.offsetX, e.offsetY];
    
    }).mouseup(function(e) {
        end = [e.offsetX, e.offsetY];
    
        var x1 = Math.min(start[0], end[0]),
            x2 = Math.max(start[0], end[0]),
            y1 = Math.min(start[1], end[1]),
            y2 = Math.max(start[1], end[1]);
    
        var grabbed = [];
        $('*').each(function() {
            if(!$(this).is(":visible")) return;
    
            var o = $(this).offset(),
                x = o.left,
                y = o.top,
                w = $(this).width(),
                h = $(this).height();
    
            if(x > x1 && x + w < x2 && y > y1 && y + h < y2) {
                grabbed.push(this);
            }
        });
        console.log(grabbed);
    
        start = null;
    
        $(this).hide();
    
    }).mousemove(function(e) {
        if(!start) return;
    
        ctx.clearRect(0, 0, this.offsetWidth, this.offsetHeight);
        ctx.beginPath();
    
        var x = e.offsetX,
            y = e.offsetY;
    
        ctx.rect(start[0], start[1], x - start[0], y - start[1]);
        ctx.fill();
    });