views:

221

answers:

2

I've been working on this for awhile, now. You might also call it a 'reverse mask', or an 'inverse mask'.

Basically, I'm creating a view window within a display object. I need to allow objects on the stage that are under the window to be able to interact with the mouse.

This is similar to a WPF question: http://stackoverflow.com/questions/740994/use-wpf-object-to-punch-hole-in-another, which has a much shorter write-up.

I've got a Class called PunchOutShield, which creates a Sprite that covers the stage (or over some desired area). The Sprite's Graphics object is filled using the color and transparency of Flex's modal screen. The result is a screen that looks like the screen which appears behind a modal PopUp.

PunchOutShield has a method called punch, which takes two arguments - the first is a Shape object, which defines the shape of the punch-through area; the second is a Point object, which indicates where to position the punch-through area.

It took some experimenting, but I found that I can successfully create a punch-out area (i.e. - the modal screen does not display within the bounds of the given Shape). To do this, I set cacheAsBitmap to true on the Sprite that is used to create the modal screen, and also on the Shape object, which is added to the modal screen Sprite's displayList.

If I set the blend mode of the Shape to ERASE, a completely transparent area is created in the modal screen. So far, great.

The problem is that Shape does not subclass InteractiveObject, so there is no way to set mouseEnabled = false on it. And so, it prevents interaction between the mouse and any objects that are visible through the punch-out area.

On top of that, InteractiveObject isn't available to look at, so I can't see if there is a way to borrow what it's doing to provide the mouseEnabled functionality and apply it to a subclass of Shape.

I've tried using another Sprite object, rather than a Shape object, but the blending doesn't work out correctly. I'm not sure why there is a difference, but the Shape object seems to somehow combine with the parenting Sprite, allowing the ERASE blendMode to effect the desired punch-out visual appearance.

It wouldn't be the end of the world if I had to draw up the screen with a series of rectangles so that the punch-out area was just simply not drawn, but that approach won't work if the punch-out area is complex. Or round.

Any thoughts on this approach, or on an alternative approach?

A: 

Is there a reason why you can't use the mask property of DisplayObject? That should allow you to put a hole in any display object.

Jacob
Hey, Jacob. Thanks a lot for the response. Setting a mask would allow me to define a visible area of the DisplayObject. In this case, I've got a 'screen' ( a semi-transparent Sprite that covers the stage). I want to put a hole in that 'screen' - say, a rectangular area 400 x 200. Setting a mask on the 'screen' would result in the screen displaying only in that 400 x 200 area. What I want to do is make the screen display as normal, _except_ for that 400 x 200 rectangular area. Basically, the reverse operation of normal masking.
Ross Henderson
I think I understand now. One approach may be to not dynamically draw the mask, but to create a large rectangle mask with a hole that is large enough so that the cut out area can be put anywhere on the stage by moving the mask.
Jacob
That's not a bad plan, but this does need to be dynamically created. Also, I want to be able to use any shape at all, not just rectangles. Your suggestion would work, though, if I created a duplicate of everything under the 'screen', and added to the display list above the screen, and masked the duplicated content with the Shape as the child of an InteractiveObject. Wouldn't scale well, but is definitely something to think about.
Ross Henderson
+1  A: 

It seems that drawing multiple shapes between beginFill() and endFill() and using the result as a mask could produce the desired effect. See also: http://www.galaxygoo.org/blogs/2007/09/shapes_unexpectedly_cancelling_1.html

martyfmelb