Question

I have a container MovieClip that serves as a content area that I need to mask off. When I create a mask inside this container using a Shape I can't seem to interact with the contents of other containers I create here, like buttons etc.

This is what I'm doing in code (I've left out all the import's etc.):

class MyContainer extends MovieClip
{
   protected var masker : Shape = null;
   protected var panel : MyPanel = null;

   public function MyContainer()
   {
      this.masker = new Shape();
      this.masker.graphics.clear();
      this.masker.graphics.beginFill( 0x00ff00 );
      this.masker.graphics.drawRect(0, 0, 1, 1);  // 1x1 pixel.
      this.masker.graphics.endFill();
      addChild( this.masker );

      this.panel = new MyPanel();  // has buttons and stuff.
      addChild( this.panel );

      this.mask = this.masker;
   }

   // called by it's parent when the stage is resized.
   public function resize( width : Number, height : Number ) : void
   {
      // set the mask to half the size of the stage.
      this.masker.width  = width  / 2;
      this.masker.height = height / 2;

      // set the panel to half the size of the stage.
      this.panel.resize( width / 2, height / 2);
   }
}

When I add the mask (Shape) to the display hierarchy I can no longer interact with whatever buttons are defined in MyPanel. However, not adding the mask to the display hierarchy does let me interact with the contents on MyPanel but the mask is not sized/positioned correctly. I guess that when the mask is not added to the display hierarchy it sits in the top-left corner of the movie (I cannot prove this though).

How do I go about making my mask size/position correctly and let the user interact with the buttons in MyPanel?

Was it helpful?

Solution

this.masker.mouseEnabled = false; //set on this.masker

That should work. Right now it is intercepting your events before they get to anything else in the container. Not 100% sure, but I believe a mask will sit on top of the container. Another option would be to add another masking child to MyContainer at the bottom of the displayList and add panel as its sibling. You will want to set mouseEnabled and mouseChildren to false on the masked sprite/mc still though.

package
{
    import flash.display.Shape;
    import flash.display.Sprite;

    public class MyContainer extends Sprite
    {
       protected var masker : Shape = null;
       protected var panel:MyPanel;

       public function MyContainer()
       {

          this.masker = new Shape();
          this.masker.graphics.clear();
          this.masker.graphics.beginFill( 0x00ff00 );
          this.masker.graphics.drawRect(0, 0, 1, 1);  // 1x1 pixel.
          this.masker.graphics.endFill();
          addChild( this.masker );

          this.panel = new MyPanel();
          this.addChild(panel);
          this.mask = this.masker;
       }

       // called by it's parent when the stage is resized.
       public function resize( width : Number, height : Number ) : void
       {
          // set the mask to half the size of the stage.
          this.masker.width  = width  / 2;
          this.masker.height = height / 2;

          // set the panel to half the size of the stage.
       }
    }
}

-

package
{
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.MouseEvent;

    public class MyPanel extends Sprite
    {
        public function MyPanel()
        {
            this.graphics.beginFill(0xFF0000)
            this.graphics.drawRect(0,0,10,10);
            this.addEventListener(MouseEvent.MOUSE_OVER, this.handleMouseOver)
            this.addEventListener(MouseEvent.MOUSE_OUT, this.handleMouseOut)
        }

        public function handleMouseOver(event:Event):void
        {
            this.graphics.clear();
            this.graphics.beginFill(0x00FF00)
            this.graphics.drawRect(0,0,10,10);
        }

        public function handleMouseOut(event:Event):void
        {
            this.graphics.clear();
            this.graphics.beginFill(0xFF0000)
            this.graphics.drawRect(0,0,10,10);
        }
    }
}

OTHER TIPS

One thing i noticed is if the mask in a child of the masked object, the position of that mask for all mouse related event or interactivity will be off, while visually everything seems fine.

For example i had a clip with a button inside end it was masked by one of it's child. What happened is only half the button could be clicked and if I moved the clip a bit to the left, only a quarter of the button remained click-able.

Basically the mouse event masking seems to position itself relative to the parent of the masked object while the visual mask does not.

You need to move the mask to the parent clip. Here how i did it :

class MaskedObject extends MovieClip{
  public var maskClip:MovieClip;
  public var maskOrigin:Point

  public function MaskedObject (){
     maskOrigin = new Point(maskClip.x,maskClip.y);
     parent.addChild(maskClip);
     maskClip.x = maskOrigin.x + this.x;
     maskClip.y = maskOrigin.y + this.y;
     mask = maskClip;
  }

  override function set x(val:Number):void{
    super.x = val;
    maskClip.x = maskOrigin.x + this.x;
  }


  override function set y(val:Number):void{
    super.y = val;
    maskClip.y = maskOrigin.y + this.y;
  }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top