Find position of objects drawn in HTML5 canvas

11,867

The better way to do this is to create a new object for each rectangle. This way you can store each object with its own properties in an array and redraw it in each cycle of your drawloop. You can access all the variables on this object whenever you wish and use it in a much more flexible way.

So I would use something like this:

function Rectangle(props){
  var posX = this.posX = props.x;
  var posY = this.posY = props.y;

  this.width = props.width;
  this.height = props.height;
  this.fill = props.fill;

  this.draw = function(){
    ctx.fillStyle = this.fill;
    ctx.fillRect(this.posX, this.posY, this.width, this.height);
  }
}

The use of this is demonstrated in this JSFiddle http://jsfiddle.net/hgh2S/

I have left off the drag events and all to make the usecase a bit more clear. You could easily implement it yourself based on this example.

Also, note the way I have hooked the button to a listener instead of directly calling JS from your HTML element. This is a much safer way to do this.

Share:
11,867
Lucy
Author by

Lucy

Updated on June 04, 2022

Comments

  • Lucy
    Lucy almost 2 years

    I'm making an HTML5 project in which the user can drag and drop multiple items inside a canvas..I want to record the position of these objects on page load and also after moving them around in the canvas.For this I'm saving all this in an array using the save() method of canvas inside the draw function to store all the context details as the draw function is called even while drawing objects in the new location..

     function draw() {
    clear();
    ctx.fillStyle = "#FAF7F8";
    rect(0, 0, WIDTH, HEIGHT);
    // redraw each rect in the rects[] array
    for (var i = 0; i < rects.length; i++) {
        var r = rects[i];
        ctx.fillStyle = r.fill;
        rect(r.x, r.y, r.width, r.height);
        pos[i]= ctx.save();
    }
    }
    

    I'm calling the value of 1st array element on button click to make sure that the context values are being stored properly..

    function position(){
    alert("pos[0]");
    }
    

    When i run this code, on button click i'm getting the output as undefined in the alert box like shown in the image below.undefined...

    The js fiddle of the above code is

    http://jsfiddle.net/qm9Eb/4/

    Please Help..

  • iamrobin
    iamrobin almost 10 years
    Sure I can :) jsfiddle.net/LYUYf/2. Note how I added the isDragging property to the Rectangle object. For each click I check the properties of each Rectangle object against the mouse position. It's not that different from how you did it. And when I drag I manipulate the properties of the clicked object, which makes sure every object always has its own values that you can use.
  • Lucy
    Lucy almost 10 years
    Could you please provide the fiddle link with all the drag events like mouseup, mousedown and mouse-moves??
  • iamrobin
    iamrobin almost 10 years
    I used your code in order to test for 'hits' on click, but i've noticed it's not that accurate. You might wanna look into how you can make it more precise. Btw, in this case your button always alerts the position of the first rectangle (the black one), but I'm sure you can come up with other cool stuff to do with it.
  • Lucy
    Lucy almost 10 years
    Yes as of now i'm only returning the position of the first rectangle just to make sure the code is working properly..Eventually my aim is to take the positions of all the rectangles..
  • iamrobin
    iamrobin almost 10 years
    Yeah ofc, that's easy to do when you just loop over the array that is holding all the rectangle objects and read out their posX and posY values. Btw, with this setup it's even easy to check wether rectangles collide with each other. Pretty handy in stuff like games.
  • Lucy
    Lucy almost 10 years
    Could you please elaborate on what you mean by 'hits' on click??
  • iamrobin
    iamrobin almost 10 years
    Sorry, it's not as hard as I made it sound. It's just the check wether the mouseclick is within the bounds of a rectangle.
  • Lucy
    Lucy almost 10 years
    Will the above approach work also with jQuery? I have made another instance using JQuery here..jsfiddle.net/gkefk/26 On double click the object gets removed also.
  • iamrobin
    iamrobin almost 10 years
    Isn't this way different, because you are not using canvas here? The important thing to remember is that in canvas you don't really have objects with a position. It's merely colouring pixels on every loop. So your javascript objects are just a way to remember which pixels you have colored. I'm sure you could somehow do it with jQuery, but keep in mind that plain javascript is much leaner than jQuery. I've never tried jquery in combination with canvas, because I think it's not that relevant in this usecase.