jquery - drawing rectangles on an image in javascript - Stack Overflow

I'm trying to write a simple java script program to mark rectangles on an image. You click a butto

I'm trying to write a simple java script program to mark rectangles on an image. You click a button to add a rectangle then you click on the upper left and lower right corner and the program should mark the rectangle in red. I'm using straight javascript with jquery.

Everything almost works, except when either the upper left or lower right corner of a rectangle is inside another rectangle in that case, while the click event gets processed, the x and y are incorrect.

I've been trying to troubleshoot this for hours and google didn't help. I specifically tried:

  • changing the e.pageX for e.screenX and e.screenY
  • using the absolute position (the top and left) instead of the offset

It is clear I'm missing something that is not allowing me to get this just right, but I don't know exactly what.

I've created a jsfiddle with an example that shows the problem. Yet in case you don't want to click on it, this is my JS code:

var rects = [{x1: 708, y1: 246, x2: 738, y2: 277},
             {x1: 442, y1: 239, x2: 474, y2: 271},
             {x1: 676, y1: 242, x2: 703, y2: 270}];

var $container = $("#container");
var click_count = 0;
var added_rects = 0;
var waiting_for_clicks = false;
var new_rects = [];
var current_rect = {};

var add_rect = function(color, rect) {
    $('<div class="child"/>')
    .appendTo($container)
    .css("left", rect.x1 + "px")
    .css("top", rect.y1 + "px")
    .css("width", (rect.x2-rect.x1)+"px")
    .css("height", (rect.y2-rect.y1)+"px")
    .css("border", "1px solid " + color);
};

var remove_last_rect = function() {
    if (new_rects.length > 0) {
        $container.children('div:last-child').remove();
        new_rects.pop();
    }
}
_.map(rects, _.partial(add_rect, 'red'));

var listen_for_rect = function() {
    click_count = 0;
    waiting_for_clicks = true;
    current_rect = {x1: -1, y1: -1, x2: -1, y2: -1};
    $('#add-rect').attr('disabled', 'disabled');
    $('#remove-rect').attr('disabled', 'disabled');
};

var stop_listening_for_rects = function() {
    waiting_for_clicks = false;
    $("#add-rect").removeAttr('disabled');
    $('#remove-rect').removeAttr('disabled');
    add_rect('red', current_rect);
    new_rects.push(current_rect);
}

$('#add-rect').click(function(e) {
    e.preventDefault();
    listen_for_rect();
});

$('#remove-rect').click(function(e) {
    remove_last_rect();
    if (new_rects.length == 0) $(this).attr('disabled', 'disabled');
});

var click_event = function(e) {
    e.preventDefault();
    if (waiting_for_clicks) {
        click_count++;
        var offset = $(this).offset();
        var x = e.pageX-offset.left;
        var y = e.pageY-offset.top;
        console.log(x);
        console.log(y);
        if (click_count == 1) {
            current_rect.x1 = x;
            current_rect.y1 = y;
        } else if (click_count == 2) {
            current_rect.x2 = x;
            current_rect.y2 = y;
            stop_listening_for_rects();
        }
    }
};

$container.on('click', '.child', click_event);

$('img').click(click_event);
// console.log($('.child'));

I'm trying to write a simple java script program to mark rectangles on an image. You click a button to add a rectangle then you click on the upper left and lower right corner and the program should mark the rectangle in red. I'm using straight javascript with jquery.

Everything almost works, except when either the upper left or lower right corner of a rectangle is inside another rectangle in that case, while the click event gets processed, the x and y are incorrect.

I've been trying to troubleshoot this for hours and google didn't help. I specifically tried:

  • changing the e.pageX for e.screenX and e.screenY
  • using the absolute position (the top and left) instead of the offset

It is clear I'm missing something that is not allowing me to get this just right, but I don't know exactly what.

I've created a jsfiddle with an example that shows the problem. Yet in case you don't want to click on it, this is my JS code:

var rects = [{x1: 708, y1: 246, x2: 738, y2: 277},
             {x1: 442, y1: 239, x2: 474, y2: 271},
             {x1: 676, y1: 242, x2: 703, y2: 270}];

var $container = $("#container");
var click_count = 0;
var added_rects = 0;
var waiting_for_clicks = false;
var new_rects = [];
var current_rect = {};

var add_rect = function(color, rect) {
    $('<div class="child"/>')
    .appendTo($container)
    .css("left", rect.x1 + "px")
    .css("top", rect.y1 + "px")
    .css("width", (rect.x2-rect.x1)+"px")
    .css("height", (rect.y2-rect.y1)+"px")
    .css("border", "1px solid " + color);
};

var remove_last_rect = function() {
    if (new_rects.length > 0) {
        $container.children('div:last-child').remove();
        new_rects.pop();
    }
}
_.map(rects, _.partial(add_rect, 'red'));

var listen_for_rect = function() {
    click_count = 0;
    waiting_for_clicks = true;
    current_rect = {x1: -1, y1: -1, x2: -1, y2: -1};
    $('#add-rect').attr('disabled', 'disabled');
    $('#remove-rect').attr('disabled', 'disabled');
};

var stop_listening_for_rects = function() {
    waiting_for_clicks = false;
    $("#add-rect").removeAttr('disabled');
    $('#remove-rect').removeAttr('disabled');
    add_rect('red', current_rect);
    new_rects.push(current_rect);
}

$('#add-rect').click(function(e) {
    e.preventDefault();
    listen_for_rect();
});

$('#remove-rect').click(function(e) {
    remove_last_rect();
    if (new_rects.length == 0) $(this).attr('disabled', 'disabled');
});

var click_event = function(e) {
    e.preventDefault();
    if (waiting_for_clicks) {
        click_count++;
        var offset = $(this).offset();
        var x = e.pageX-offset.left;
        var y = e.pageY-offset.top;
        console.log(x);
        console.log(y);
        if (click_count == 1) {
            current_rect.x1 = x;
            current_rect.y1 = y;
        } else if (click_count == 2) {
            current_rect.x2 = x;
            current_rect.y2 = y;
            stop_listening_for_rects();
        }
    }
};

$container.on('click', '.child', click_event);

$('img').click(click_event);
// console.log($('.child'));
Share Improve this question edited Mar 27, 2013 at 4:40 carlosdc asked Mar 27, 2013 at 4:32 carlosdccarlosdc 12.2k4 gold badges47 silver badges64 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 3

If you click inside of a rect, then the x and y co-ordinates are relative to the top left corner of the rect, rather than the top left corner of the image.

The reason is, $(this).offset() returns the offset of the element you're clicking in, not the offset of the image, so when you click inside of a rect it returns the offset of the rect.

Try this in click_event = function(e) {:

var offset = $("img").offset();

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745329343a4622803.html

相关推荐

  • jquery - drawing rectangles on an image in javascript - Stack Overflow

    I'm trying to write a simple java script program to mark rectangles on an image. You click a butto

    3小时前
    10

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信