views:

33

answers:

2

Hi All,

I have the following piece of code written using mootools and mootools canvas library.

CANVAS.init({ canvasElement : 'canvas', interactive : true });

var itemlayer = CANVAS.layers.add({ id : 'items' });

for(var j = 0; j < 5; j++)
{
for(var i = 0; i < 5; i++)
{

    itemlayer.add({

        id : 'item-'+i + '-' + j,
        x : 51 * i,
        y : 51 * j,
        w : 50,
        h : 50,
        state : 'normal',
        interactive : true, //although they have no interactive events!
        colors : { normal : '#f00', hover : '#00f' },
        events : {
            onDraw : function(ctx){

                    ctx.fillStyle = this.colors[this.state];
                    ctx.fillRect(this.x,this.y,this.w,this.h);

                    this.setDims(this.x,this.y,this.w,this.h);
            }
        }

    });


}

}

CANVAS.addThread(new Thread({
            id : 'myThread',
            onExec : function(){
                    CANVAS.clear().draw();
            }
    }));

Now what I would like to do is destroy the squares soon after they are drawn on the canvas.

The function given in the documentation to do so is

item.destroy( );

Refer here.

The problem is, no matter how I do it, I am not able to destroy the objects from the canvas! What would be the correct way to do it?

Refer code here implemented on js fiddle.

A: 

I'm not familiar with the innards of mootools, but it looks like item.destroy() merely dispatches an event rather than actually destroys the item on the canvas. The canvas is merely a bitmap - it doesn't have layers or records of individual primitives like SVG does.

You would need to actually destroy the rectangles yourself by redrawing the canvas without them, drawing over them, or use:

ctx.clearRect(this.x, this.y, this.w, this.h);

This will clear all info on the canvas within the rectangle defined by the parameters.

edit: After doing a little reading, it looks like you pass a destroy() function to the constructor of your canvas item. This function must contain whatever code you want to destroy your item (clearRect, fillRect, whatever).

C-Mo
But then I would like to clear the item ID and would like another item to reuse that ID. Are you telling me that the destroy item will not allow me to reuse the itemID i.e once the item is assigned an ID it cannot be destroyed?
Shouvik
You can probably re-use the item ID, but firing the object's destroy event without any underlying code won't make the object disappear from the canvas. You need to clear the pixels yourself by writing your own function for the destroy event, because the canvas doesn't know what "objects" are drawn on it - only that there's a certain color at (x,y).
C-Mo
A: 

Mootools is a class based JavaScript framework. In order to use it you need to call objects as if they were classes and not their constructors directly.

The CANVAS library is an exception to the rule as it is a "static" class. However, before you can use layer methods, you need to initialize the layer class.

When you use the add method of the Layer class, you are asking for new items to be added to that Layer class. You use this method twice, once just before the loop and once just inside it. However, at no point do you initialize the layer class. Therefore, I assume that case before the loop is supposed to initialize the class. This needs to be replaced with var itemlayer = new Layer('items');

When using itemlayer.add inside the loop, you are passing and object to the Layer object which is then automatically creating the CanvasItem objects for you. It then returns these objects to you. Since the destroy method is a member of the CanvasItem class, you need to catch them in a variable in order to call it. Since it is happening inside a loop, if you wish to delete the objects outside of the loop, you will need an array.

CANVAS.init({ canvasElement : 'canvas', interactive : true });

var itemlayer = new Layer('items');
var itemArray = new Array;
for(var j = 0; j < 5; j++)
{
for(var i = 0; i < 5; i++)
{

    item Array[j][i] = itemlayer.add({

        id : 'item-'+i + '-' + j,
        x : 51 * i,
        y : 51 * j,
        w : 50,
        h : 50,
        state : 'normal',
        interactive : true, //although they have no interactive events!
        colors : { normal : '#f00', hover : '#00f' },
        events : {
            onDraw : function(ctx){

                    ctx.fillStyle = this.colors[this.state];
                    ctx.fillRect(this.x,this.y,this.w,this.h);

                    this.setDims(this.x,this.y,this.w,this.h);
            }
        }

    });


}

Then when you wish to destroy an item, as long as you know its j and i index, you can delete it with itemArray[j][i].destroy().

Finally, keep in mind that the destroy method is only documented as firing the CanvasItem's destroy event. Depending on what the library has implemented, you may need to write your own destroy event in order to actually remove it from the canvas.

Rupert
Hi Rupert. I actually wanted to free the item instead of just using the destroy item function that merely removes the image. I instead tried using the remove function in the same library and came across huge problems. So I got some help and soon found a bug in the source. please refer this question. http://stackoverflow.com/questions/3749880/i-am-able-to-draw-the-box-but-i-am-not-able-to-remove-it-canvas
Shouvik