Forum Moderators: open

Message Too Old, No Replies

Draw rectangle and text on an image

draw javascript rectangle image

         

horseatingweeds

9:21 pm on Nov 15, 2015 (gmt 0)

10+ Year Member



What is the best way to draw and re-draw rectangles on an image with JavaScript?

Here is what I'm trying to do. I have a program written in Java. I plan to move it to a web server because of the amount of CPU resources it uses. The program displays an image with a grid overlay. The user can indicate regions of the image by clicking in the grid. When a grid cell is clicked -- which is a rectangle -- it cycles from one color to the other and text is likewise cycled. In the desktop Java program I do this by making a copy of the original image and drawing rectangles on it with OpenCV library. Each time the user clicks, a fresh copy of the image has the updated grid drawn on it before it's displayed.

How might I do this in JavaScript? I could still use my current method combined with AJAX, but the user would have to wait for a round trip of the image on every click. It would be nice to have a JavaScript way of immediately updating the grid on each click.

lucy24

9:42 pm on Nov 15, 2015 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Is this happening within a <canvas> element?

horseatingweeds

12:25 am on Nov 16, 2015 (gmt 0)

10+ Year Member



Sure.

lucy24

1:03 am on Nov 16, 2015 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



:: madly shuffling papers because I know I've done this but don't have the command internalized ::

Oh, right. You make a second, invisible canvas with exactly the same content as the one the user sees, and always draw a copy to that canvas right after you've drawn to the visible one.

There's a disorienting bit of asymmetry because the command for copying from one to the other is in the form
newcontext.drawImage(oldcanvas,0,0);
(with a bunch more parameters if you're only drawing one part of each canvas so you need your left/right width/height and so on), where newcontext is a context (generated by a function you've presumably already got) while oldcanvas is the canvas itself (using the id name of one of the two canvases).

... and that explains why my code uses those two names. It's so that when I look at it more than a year later, I'll remember which is which.

:: vaguely looking around for Fotiman or someone like him ::

Fotiman

8:02 pm on Nov 19, 2015 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Sorry, haven't been around as much as usual. :)
You really don't need a canvas for this (though that's certainly a valid approach). I haven't touched canvas in ages... I could probably whip up a solution using that given a little bit of time, but instead I came up with a different alternative:

[codepen.io...]

That approach uses jQuery. You could do this without jQuery, but jQuery makes DOM manipulation easy. Basically, create the image element and include it in your DOM. Then create a "grid" overlay element that will be positioned on top of your image, and add a click handler. Note, some of the values may need more careful monitoring. For example, the first row has a "bottom" value of 59, while the second row has a top value of 58.6875. I believe this is because we're dividing for the number of columns and rows, which may result in floating point values. I haven't investigated closely, but depending on your application, that may or may not be an issue for you.

Fotiman

2:50 pm on Nov 20, 2015 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Note, I discovered that the load event on images is not consistent. The link above may be in some flux until I nail down a more consistent solution.

Edit: Ok, I think it should be working consistently now. :)

horseatingweeds

1:24 pm on Dec 2, 2015 (gmt 0)

10+ Year Member



Thanks, Lucy24. So, essentially, bring the image file in once, store it in two canvas elements, one invisible one not, drawing the rectangles on the visible one, and each time the rectangles need to be redrawn make a fresh copy of the safely stored image in the invisible canvas element? That is simple enough.

lucy24

8:56 pm on Dec 2, 2015 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Right. Check back if it doesn't work as intended, because everyone will want to know about it.