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?
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?
Share Improve this question asked Apr 28, 2012 at 19:33 Seany242Seany242 3737 silver badges20 bronze badges5 Answers
Reset to default 2I 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
}
I found that this tutorial really helped me get my head around the subject.
http://simonsarris./blog/510-making-html5-canvas-useful
He walks through the creation of objects, keeping track of the state, handling mouse events, etc.
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 plex 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 mon for applications using canvas (for example games).
Here's a plete exemple : 3 rects are moved and redrawn every 10 ms.
http://jsfiddle/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).
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.
First you have to bine 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 position 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);