Update: I’ve updated the InvertedMask-class with a few new features. You can find the new and updated version here.
I love masks. I really do. I use them alot and I’m proud of it. But a lot of times I need to make something I think Adobe should put into Flash as a native alternative to the regular mask. And that is the inverted mask.
I know more people than me miss this feature and I for one would love to see something like DisplayObject.invertedMask = MaskObject; but its no where to be found unless you want to make your own AS3-solution, which I think is more or less a workaround for something that should have been there from the start.
I’ve seen some people using blendmodes to achive the same effect like the one from Rachel Diesel (http://dieselation.com/2009/04/11/inverting-a-mask-in-actionscript-3/) but most of the time they are not pure as3 so I modified her solution into a more reusable piece of code. And I also added the function moveMask() which allowes you to move the inverted mask after it has been added to the stage with out any hazzle.
It’s not perfect and I bet that a lot of improvements can be done but you can try out the demo here. And yes, that is a pink elephant in a fake Guccibag.
package com.mattiasnorell.bitmap
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.BlendMode;
import flash.display.DisplayObject;
import flash.display.Sprite;
import flash.geom.ColorTransform;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.geom.Rectangle;
/**
* ...
* Original author: Rachel Diesel
* http://dieselation.com/2009/04/11/inverting-a-mask-in-actionscript-3/
*
* Pure AS3 code Mattias Norell
* http://blog.mattiasnorell.com/2009/10/21/pure-actionscript-3-inverted-mask/
*
*/
public class InvertedMask extends Sprite{
public function InvertedMask($parent:DisplayObject,$mask:DisplayObject,$maskPos:Object):void {
var inverted:Sprite = new Sprite();
inverted.x = $parent.x;
inverted.y = $parent.y;
var dup:BitmapData = new BitmapData($mask.width, $mask.height, true, 0xffffff);
dup.draw($mask);
var newAlpha:Bitmap = new Bitmap(dup, "auto", true);
newAlpha.x = $maskPos.x;
newAlpha.y = $maskPos.y;
newAlpha.blendMode = BlendMode.ERASE;
$mask.parent.removeChild($mask);
inverted.addChild($parent);
$parent.x=$parent.y = 0;
inverted.addChild(newAlpha);
inverted.blendMode = BlendMode.LAYER;
addChild(inverted);
}
public function moveMask($target:Object,$maskPos:Object):void {
$target.getChildAt(0).getChildAt(1).x = $maskPos.x;
$target.getChildAt(0).getChildAt(1).y = $maskPos.y;
}
}
}
To activate it you just copy/paste this into your project.
The first parameter is the object you want to mask, the second is the mask itself and in the third parameter you tell the mask where along the x and y-axis it should go.
var newMask:InvertedMask = new InvertedMask(OBJECT_TO_BE_MASKED, THE_MASK, { x:0, y:0 } );
addChild(newMask);
What about moving the mask?
If you add an eventListener to the InvertedMask-object and call the function below it will move your mask in anyway you want.
newMask.addEventListener(MouseEvent.MOUSE_MOVE, moveMask);
private function moveMask(e:MouseEvent):void {
e.currentTarget.moveMask(e.currentTarget, { x:mouseX-10, y:mouseY-10 } );
}
So, all credits for the solution goes to Rachel, I’ve just tweaked it a little to suit my needs and as I said, it’s not perfect but it’s a start.
Hi, great work with InvertedMask class, but for my project I would need the functionality of the invertedmask class to be dynamic, so that the user could draw a mask using lineto dynamically and that would be applied real time to masked shape.
Do you think this is possible?
Pingback: Dynamic mask using ActionScript « blog.mattiasnorell.com
Hey, great that you found the class useful. At the moment you cant do that with my class, but it can be done. I just wrote a little thing that does almost what I think you are looking for (http://blog.mattiasnorell.com/2010/01/15/dynamic-mask-using-actionscript/) and I plan to extend my invertedmask-class with something like that so that it becomes more dynamic. I´ll write a post about it when it´s finished.