Copy link to clipboard
Copied
Hi,
I'm trying to create a dark overlay layer on top of some graphics, but want to "cut" a transparent circular hole in that dark layer so only that circular part will be seen, and the rest will seem dark (similar to method used to explain a game or an app in Android, which hides most of the screen by a dark layer, and reveals only parts I want to highlight). I've been trying to use BlendModes, specifically the ALPHA or ERASE modes, but this is not working for me...
This is what I have so far:
I created a black rectangle of the size of the stage and gave it the LAYER bland mode (as i read was needed for the ALPHA blend mode to work), then I added my circle and gave it ALPHA blend mode and set alpha = 0 to be transparent. I see the black layer, but not the transparent circle inside it...
Any help would be appreciated!
var mc:MovieClip = new MovieClip();
var rectangle:Shape = new Shape; // initializing the variable named rectangle
rectangle.graphics.beginFill(0x000000); // choosing the colour for the fill, here it is red
rectangle.graphics.drawRect(0, 0, stage.stageWidth,stage.stageHeight); // (x spacing, y spacing, width, height)
rectangle.graphics.endFill(); // not always needed but I like to put it in to end the fill
rectangle.blendMode = BlendMode.LAYER;
rectangle.alpha = 0.8;
mc.addChild(rectangle); // adds the rectangle to the stage
var circle:Shape = new Shape(); // The instance name circle is created
circle.graphics.beginFill(0xFFFFFF, 1); // Fill the circle with the color 990000
circle.graphics.lineStyle(2, 0x000000); // Give the ellipse a black, 2 pixels thick line
circle.graphics.drawCircle(stage.stageWidth/2, stage.stageHeight/2, 200); // Draw the circle, assigning it a x position, y position, raidius.
circle.graphics.endFill(); // End the filling of the circle
circle.blendMode = BlendMode.ALPHA;
circle.alpha = 0;
mc.addChild(circle); // Add a child
stage.addChild(mc); // Add a child
Hi.
You should set the parent Movie Clip to LAYER and the inner circle to ERASE.
Like this:
...var mc:MovieClip = new MovieClip();
var rectangle:Shape = new Shape; // initializing the variable named rectangle
var circle:Shape = new Shape(); // The instance name circle is created
mc.blendMode = BlendMode.LAYER;
rectangle.graphics.beginFill(0x000000); // choosing the colour for the fill, here it is red
rectangle.graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight); // (x spacing, y spacing, width, he
Copy link to clipboard
Copied
Hi.
You should set the parent Movie Clip to LAYER and the inner circle to ERASE.
Like this:
var mc:MovieClip = new MovieClip();
var rectangle:Shape = new Shape; // initializing the variable named rectangle
var circle:Shape = new Shape(); // The instance name circle is created
mc.blendMode = BlendMode.LAYER;
rectangle.graphics.beginFill(0x000000); // choosing the colour for the fill, here it is red
rectangle.graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight); // (x spacing, y spacing, width, height)
rectangle.graphics.endFill(); // not always needed but I like to put it in to end the fill
rectangle.alpha = 0.8;
mc.addChild(rectangle); // adds the rectangle to the stage
circle.graphics.beginFill(0xFFFFFF, 1); // Fill the circle with the color 990000
circle.graphics.lineStyle(2, 0x000000); // Give the ellipse a black, 2 pixels thick line
circle.graphics.drawCircle(stage.stageWidth / 2, stage.stageHeight / 2, 200); // Draw the circle, assigning it a x position, y position, raidius.
circle.graphics.endFill(); // End the filling of the circle
circle.blendMode = BlendMode.ERASE;
mc.addChild(circle); // Add a child
stage.addChild(mc); // Add a child
I hope this helps.
Regards,
JC
Copy link to clipboard
Copied
Thank you JC so much !
It works now!
I was so close... but close is not enough...
I had to give the LAYER blend mode to the containing MC and not to the lower graphic element like I did.
BTW, how did you format the code you added as a "code"? I couldn't find where to style it as a "code" instead of just plain text.
Thank you very much!
Koby
Copy link to clipboard
Copied
You're welcome!
There is a link in the upper right corner that says "Use advanced editor".
Once inside this editor, look for a double arrow icon on the right, select Syntax Highlighting > javascript.
Most of time it won't tab the code for you. So you'll have to do it manually.
Copy link to clipboard
Copied
Thanks! Will try that next time I write code.
BTW, do you know if there is a way to make the transparent circle in my MovieClip above "see through" for mouse clicks...?
I mean, when I place the MovieClip i can see the objects below, but any mouse event is probably going to the MovieClip and is not reaching the objects below... Is there a way to make the transparent part also transparent to mouse clicks? or make the entire MovieClip transparent to clicks...?
Copy link to clipboard
Copied
Sure.
Try mc.mouseEnabled = false;
EDIT: Obviously you only want the clicks only inside the circle. Sorry.
I'll get back to you.
Copy link to clipboard
Copied
Please try this:
function enterFrameHandler(e:Event):void
{
if (distanceBetweenTwoPoints(mouseX, mouseY, stage.stageWidth * 0.5, stage.stageHeight * 0.5) < 200) // 200 is the radius of the circle
mc.mouseEnabled = false;
else
mc.mouseEnabled = true;
}
function distanceBetweenTwoPoints(x1:Number, y1:Number, x2:Number, y2:Number):Number
{
var dx:Number = x1-x2;
var dy:Number = y1-y2;
return Math.sqrt(dx * dx + dy * dy);
}
stage.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
Copy link to clipboard
Copied
Wow, great trick JC !
(calculating the distance from the center of the circle, and thus knows if the mouse is inside or outside the circle)
That can be easily adapted for rectangle "holes" instead of circular ones.
I tried that on PC with mouse, and it works perfectly.
On Android (Adobe AIR) it requires additional touch before recognizing a change in the area.
So one touch to the black BG will go through, but next touches will be blocked.
Then one touch in the transparent hole will be ignored, but next touches will work.
I guess I can live with that.
I guess the ENTER_FRAME gets a lower priority than the MOUSE_UP events...
Or maybe this is because of the order I added the event listeners...?
(I added the event listener of the ENTER_FRAME after I added the MOUSE_UP)
Thank you very much!
Koby
EDIT: Changing the order of calls to addEventListener, and calling ENTER_FRAME first didn't change the behavior.
So I guess the MOUSE_UP priority is indeed higher than ENTER_FRAME
Find more inspiration, events, and resources on the new Adobe Community
Explore Now