3

I have a component that contains 4 layers: (in ascending depth order) bgImage:Sprite, dropZone:Sprite, dropMask:Sprite and line:Sprite. The bgImage is at 0,0, and the other objects are placed at various positive coordinates. dropMask is masking dropZone.

At the point of bitmap capture I want to only draw from the dropZone and dropMask layers, so I'm trying this:

removeChild(bgImage);
removeChild(line);
var bmd:BitmapData = new BitmapData(dropMask.width,dropMask.height,true,0);
bmd.draw(this,null,null,null,dropMask.getBounds(this));

Despite the dropMask being located at 50,60 the capture always starts from 0,0. I've also tried getting the boundary rectangle and forcing the x,y, but it makes no difference. What am I doing wrong here, and should I just forget clipRect and use a matrix instead?

shanethehat
  • 15,460
  • 11
  • 57
  • 87

2 Answers2

7

A common routine for that:

var rect:Rectangle = dropMask.getRect(dropMask.parent);
var matrix:Matrix = new Matrix();
matrix.translate(-rect.x, -rect.y);
var bmp:BitmapData = new BitmapData(rect.width, rect.height, false, 0xFFFF0000);
bmp.draw(dropMask.parent, matrix);

Solution steps:

  1. get a rectangle in coordinate space of what you are going to draw.
  2. get identity matrix, and translate it by -rectangle.x, -rectangle.y
  3. use this matrix in draw() call.

In step 1 you may even encounter something like that:

import flash.display.Sprite;

var test:Sprite = new Sprite();
test.graphics.beginFill(0, 1);
test.graphics.drawCircle(125, 234, 100);
test.graphics.endFill();

// we are going to draw test, so we get a rectangle 
// in its own coordinate space to deal with registration point offset
var rect:Rectangle = test.getRect(test);
var matrix:Matrix = new Matrix();
matrix.translate(-rect.x, -rect.y);
var bmp:BitmapData = new BitmapData(rect.width, rect.height, false, 0xFFFF0000);
bmp.draw(test, matrix);

// see if we are done
addChild(new Bitmap(bmp));

When I code something that uses a lot of drawing clips, I create a matrix and reuse it each time, doing matrix.identity(); to reset transforms. No need to create new matrix for each drawing.

EDIT And no, clipRect doesn't help here. You use it only when you want to draw somthing partially, not the whole clip.

Michael Antipin
  • 3,522
  • 17
  • 32
  • Yes, this is what I ended up doing, and then going further to make the matrix prefrom scaling and positioning at the same time. – shanethehat Jun 29 '11 at 14:05
0

Nevermind, I've misunderstood the purpose of clipRect. http://pixelwelders.com/blog/actionscript-3/2008/as3-bitmapdata-foibles/. Using a matrix for this is easy and solves the problem.

var mat:Matrix = new Matrix(1,0,0,1,-offsetX,-offsetY);
bmd.draw(this,mat);
shanethehat
  • 15,460
  • 11
  • 57
  • 87