4

Is it possible to store a rectangle in a variable in order to access that variable and move it around? Something like:

var rect = new Rect();
/* then in update() method */
rect.x += 5;
rect.y += 5;

Is something like this possible, or do you have to create a new rectangle using context each time? If this is the only possible way, I don't understand how you can target each rectangle drawn in the canvas. Can someone please explain this to me?

5 Answers 5

2

I would save a model of all the rectangles you want to draw with their coordinates. Then, you just have to listen to the mouseclick event (or mouseover event, whatever your needs) and browse through each element of your model to see if the mouse click was done inside the coordinates of a rectangle.

As the previous posters said, you have to redraw your canvas every time you want to make a change to it (although you can speed things up by redrawing only the region of interest). Hope that helps a bit!

EDIT:

you could have a rectangle object defined:

function Rectangle(x, y, w, h) {
    this.x = x;
    this.y = y;
    this.w = w;
    this.h = h;

    this.contains = function(x, y) {
        return (x > this.x && x <= (this.x + this.w) &&
            y > this.y && y <= (this.y + this.h));
    }

    this.clone = function() {
        return new Dimension(this.x, this.y, this.w, this.h);
    }
}

and then have an array that would be your model :

var model = [];

And then add your rectangles to it:

model.push(new Rectangle(10,10,10,10));//x, y, width, height

Then, when you click on your canvas, you retrieve the mouse click coordinates from the mouse event and you loop over your array to see if the click was done inside one of the rectangles:

for (i = 0 ; i < model.length ; i++) {
 if (model[i].contains(mouseEvent.x, mouseEvent.y))
  //do something like redraw your canvas
}
1
  • "I would save a model of all the rectangles you want to draw with their coordinates." - How do i do this?
    – Seany242
    Commented Apr 29, 2012 at 0:39
2

I found that this tutorial really helped me get my head around the subject.

http://simonsarris.com/blog/510-making-html5-canvas-useful

He walks through the creation of objects, keeping track of the state, handling mouse events, etc.

2

HTML5 Cancas has a bitmap model : when you draw you modify the pixels of the canvas, and you can read the pixels if you want, but the logic of the pixels (lines, rects, etc.) is lost.

The canvas model is very fast, enables to do complex things that would be too long in an object/vectoriel model but the limit is that you can't change or remove drawn objects like rects.

If you want to do so, you need to use a vectoriel/object model, like SVG (or plain DOM objects).

If you want to use canvas and objects, a solution is to keep your rect variables (like the one you did) in plain javascript (outside your canvas) and simply redraw the whole canvas each time you change a rect. It's efficient and common for applications using canvas (for example games).

Here's a complete exemple : 3 rects are moved and redrawn every 10 ms.

http://jsfiddle.net/dystroy/PkzDA/

I made it very simple but clean and efficient. You can use this kind of logic in real and fast applications (I do).

2
  • thanks a ton - how do I keep my rect variable in plain javascript outside my canvas like you said? Could you provide an example please? Thanks!
    – Seany242
    Commented Apr 29, 2012 at 0:44
  • 1
    I had some time this morning so I built a complete example : see updated answer. Commented Apr 29, 2012 at 6:16
1

If you want to move rectangle on the canvas you will need to clear and redraw that rectangle every time you change x or y.

1

First you have to combine what I will say with what @Gaet said

Now about reducing context effort: An option to reuse the same canvas context without erasing it is to change the way the rectangle is drawn.

You have to change the composition style to 'xor' so whenever you draw the rectangle twice it will disappear an you will be able to paint it to a new location.

See bellow example:

//this will switch context to xor mode
ctx.globalCompositeOperation = 'xor';

//this will paint the rectangle
ctx.fillRect(0, 0, 100, 100);

//this will remove the rectangle
ctx.fillRect(0, 0, 100, 100);

Not the answer you're looking for? Browse other questions tagged or ask your own question.