I have a code to erase a masked movieclip. (credits here)
I would like to know how I can check if the whole movieclip is been erased.
So I thought I had to check if the BitmapData is empty, but I could be terribly wrong!
How can I check if every pixel of the movieclip has been erased?
Of course my example below is wrong, but I think it has to be something like that.
if (erasableBitmapData = empty)
{
trace("empty")
}
var lineSize:Number=40;
var doDraw:Boolean=false;
var resumeDrawing:Boolean=false;
var erasableBitmapData:BitmapData = new BitmapData(700, 500, true, 0xFFFFFFFF);
var erasableBitmap:Bitmap = new Bitmap(erasableBitmapData);
erasableBitmap.cacheAsBitmap = true;
addChild(erasableBitmap);
maskee.cacheAsBitmap = true;
maskee.mask = erasableBitmap;
var eraserClip:Sprite = new Sprite();
initEraser();
function initEraser():void {
eraserClip.graphics.lineStyle(lineSize,0xff0000);
eraserClip.graphics.moveTo(stage.mouseX,stage.mouseY);
}
var drawnBitmapData:BitmapData = new BitmapData(700, 500, true, 0x00000000);
var drawnBitmap:Bitmap = new Bitmap(drawnBitmapData);
stage.addEventListener(MouseEvent.MOUSE_MOVE,maskMove);
stage.addEventListener(MouseEvent.ROLL_OUT, maskOut);
stage.addEventListener(MouseEvent.ROLL_OVER,maskOver);
stage.addEventListener(MouseEvent.MOUSE_DOWN,startDrawing);
stage.addEventListener(MouseEvent.MOUSE_UP,stopDrawing);
function startDrawing(e:MouseEvent):void {
eraserClip.graphics.moveTo(stage.mouseX,stage.mouseY);
doDraw=true;
}
function stopDrawing(e:MouseEvent):void {
doDraw=false;
resumeDrawing = false;
}
function maskOut(e:Event):void {
if (doDraw){
resumeDrawing = true;
}
}
function maskOver(e:MouseEvent):void {
if (resumeDrawing){
resumeDrawing = false;
eraserClip.graphics.moveTo(stage.mouseX,stage.mouseY);
}
}
function maskMove(e:MouseEvent):void {
if (doDraw && !resumeDrawing){
eraserClip.graphics.lineTo(stage.mouseX,stage.mouseY);
drawnBitmapData.fillRect(drawnBitmapData.rect, 0x00000000);
drawnBitmapData.draw(eraserClip , new Matrix(), null, BlendMode.NORMAL);
erasableBitmapData.fillRect(erasableBitmapData.rect, 0xFFFFFFFF);
erasableBitmapData.draw(drawnBitmap, new Matrix(), null, BlendMode.ERASE);
}
e.updateAfterEvent();
}
reset_btn.addEventListener(MouseEvent.CLICK,reset);
function reset(e:Event):void {
eraserClip.graphics.clear();
initEraser();
erasableBitmapData.fillRect(erasableBitmapData.rect, 0xFFFFFFFF);
}
You can check if getColorBoundsRect
returns an rectangle with an width and height of 0
for the colour you consider as 'empty', setting the findColor
argument to false. There are other ways to do this, but this is at least many times faster than checking every single pixel.
The default value of true for the findColor
argument gives you an rectangle that encloses all pixels for those (pixelColor & mask) == emptyColor
is true. When dealing with alpha values, a mask of 0xFF000000
can be used to ignore rbg values of a pixel and to only check its alpha value. So the mask 0xFF000000
and the colour 0xFF000000
would match all fully opaque pixels, while the mask 0xFF000000
and the colour 0x00000000
would match all fully transparent pixels. As meddlingwithfire pointed out, this won't do the job here. By setting findColor
to false, this process is kind of reversed so that the rectangle will enclose all pixels that are not using the empty colour. For bitmaps containing no other colours, the result will be a rectangle with an area of 0
.
var maskColor:uint = 0xFF000000;
var emptyColor:uint = 0x00000000;
var bounds:Rectangle = erasableBitmapData.getColorBoundsRect(maskColor, emptyColor, false);
if (bounds.width == 0 && bounds.height == 0){
trace("empty"); // no visible pixels
}
Technically there is a difference between a black transparent pixel 0x00000000
and for example a red transparent pixel 0x00FF0000
- but there is no visible difference (both are invisible) so you should ignore the rgb values completely, as I did in the example by using that particular mask.