AS3 get Bitmap from Movieclip with Mask - actionscript-3

This works:
var a:BitmapData = new BitmapData(640,480);
var b:Bitmap = new Bitmap(a);
a.draw(movieClip);
This doesn't work:
movieClip.mask = movieClipMask;
var a:BitmapData = new BitmapData(640,480);
var b:Bitmap = new Bitmap(a);
a.draw(movieClip);
How can I draw just the visible part of a MovieClip (that uses a mask) into my Bitmap?

Create a new Sprite and add both the MovieClip and its mask to it. Then draw the parent Sprite.
var container:Sprite = new Sprite();
container.addChild (movieClip);
container.addChild (movieClipMask);
movieClip.mask = movieClipMask;
var a:BitmapData = new BitmapData(640,480);
var b:Bitmap = new Bitmap(a);
a.draw(container);

Related

How do I remove graphics in AS3 by choosing another alternative in a combobox?

I need help to clear the previous graph I made by clicking on a alternative in my combobox, WHEN I click the other alternative in the combobox.
The coding might seem long and unnecessary, but I don't seem to find an easier way to write it.
This project is about making a bar graph with content about accidents from drunk driving and speeding. Therefore I'm using a combobox to choose to show either the speeding graph or drunk driving graph.
cmpVelg.addItem({label:"Promillekjøring"});
cmpVelg.addItem({label:"Ulovelig hastighet"});
cmpVelg.addEventListener(Event.CHANGE, klikk);
function klikk(evt:Event):void
{
if (cmpVelg.selectedItem.label == "Promillekjøring")
{
{
var proen:Shape = new Shape();
proen.graphics.lineStyle(2,0x660000,1);
proen.graphics.beginFill(0x660000);
proen.graphics.drawRect(90,170,30,180);
proen.graphics.endFill();
this.addChild(proen);
var proto:Shape = new Shape();
proto.graphics.lineStyle(2,0x660000,1);
proto.graphics.beginFill(0x660000);
proto.graphics.drawRect(160,270,30,80);
proto.graphics.endFill();
this.addChild(proto);
var protre:Shape = new Shape();
protre.graphics.lineStyle(2,0x660000,1);
protre.graphics.beginFill(0x660000);
protre.graphics.drawRect(230,300,30,50);
protre.graphics.endFill();
this.addChild(protre);
var profire:Shape = new Shape();
profire.graphics.lineStyle(2,0x660000,1);
profire.graphics.beginFill(0x660000);
profire.graphics.drawRect(300,320,30,30)
profire.graphics.endFill();
this.addChild(profire);
var profem:Shape = new Shape();
profem.graphics.lineStyle(2,0x660000,1);
profem.graphics.beginFill(0x660000);
profem.graphics.drawRect(370,280,30,70)
profem.graphics.endFill();
this.addChild(profem);
var proseks:Shape = new Shape();
proseks.graphics.lineStyle(2,0x660000,1);
proseks.graphics.beginFill(0x660000);
proseks.graphics.drawRect(440,280,30,70);
proseks.graphics.endFill();
this.addChild(proseks);
}
}
if (cmpVelg.selectedItem.label == "Ulovelig hastighet")
{
{
var has1:Shape = new Shape();
has1.graphics.lineStyle(2,0x660000,1);
has1.graphics.beginFill(0x660000);
has1.graphics.drawRect(90,310,30,40);
has1.graphics.endFill();
this.addChild(has1);
var has2:Shape = new Shape();
has2.graphics.lineStyle(2,0x660000,1);
has2.graphics.beginFill(0x660000);
has2.graphics.drawRect(160,270,30,80);
has2.graphics.endFill();
this.addChild(has2);
var has3:Shape = new Shape();
has3.graphics.lineStyle(2,0x660000,1);
has3.graphics.beginFill(0x660000);
has3.graphics.drawRect(230,210,30,140);
has3.graphics.endFill();
this.addChild(has3);
var has4:Shape = new Shape();
has4.graphics.lineStyle(2,0x660000,1);
has4.graphics.beginFill(0x660000);
has4.graphics.drawRect(300,210,30,140);
has4.graphics.endFill();
this.addChild(has4);
var has5:Shape = new Shape();
has5.graphics.lineStyle(2,0x660000,1);
has5.graphics.beginFill(0x660000);
has5.graphics.drawRect(370,200,30,150);
has5.graphics.endFill();
this.addChild(has5);
var has6:Shape = new Shape();
has6.graphics.lineStyle(2,0x660000,1);
has6.graphics.beginFill(0x660000);
has6.graphics.drawRect(440,150,30,200);
has6.graphics.endFill();
this.addChild(has6);
}
}
}
You create two graphs but do not addChild() them yet. Also you need to create the graphs just once, instead of making new shapes per click. Like this:
var promilleGraph:Sprite; // object wide variables! Important!
var uloveligGraph:Sprite;
function init(e:Event=null):void {
// or into the constructor of your main
promilleGraph=new Sprite(); // creating promille graph
var proen:Shape = new Shape();
proen.graphics.lineStyle(2,0x660000,1);
proen.graphics.beginFill(0x660000);
proen.graphics.drawRect(90,170,30,180);
proen.graphics.endFill();
promilleGraph.addChild(proen);
var proto:Shape = new Shape();
proto.graphics.lineStyle(2,0x660000,1);
proto.graphics.beginFill(0x660000);
proto.graphics.drawRect(160,270,30,80);
proto.graphics.endFill();
promilleGraph.addChild(proto);
var protre:Shape = new Shape();
protre.graphics.lineStyle(2,0x660000,1);
protre.graphics.beginFill(0x660000);
protre.graphics.drawRect(230,300,30,50);
protre.graphics.endFill();
promilleGraph.addChild(protre);
var profire:Shape = new Shape();
profire.graphics.lineStyle(2,0x660000,1);
profire.graphics.beginFill(0x660000);
profire.graphics.drawRect(300,320,30,30)
profire.graphics.endFill();
promilleGraph.addChild(profire);
var profem:Shape = new Shape();
profem.graphics.lineStyle(2,0x660000,1);
profem.graphics.beginFill(0x660000);
profem.graphics.drawRect(370,280,30,70)
profem.graphics.endFill();
promilleGraph.addChild(profem);
var proseks:Shape = new Shape();
proseks.graphics.lineStyle(2,0x660000,1);
proseks.graphics.beginFill(0x660000);
proseks.graphics.drawRect(440,280,30,70);
proseks.graphics.endFill();
promilleGraph.addChild(proseks);
// creating speeding graph
uloveligGraph=new Sprite();
var has1:Shape = new Shape();
has1.graphics.lineStyle(2,0x660000,1);
has1.graphics.beginFill(0x660000);
has1.graphics.drawRect(90,310,30,40);
has1.graphics.endFill();
uloveligGraph.addChild(has1);
var has2:Shape = new Shape();
has2.graphics.lineStyle(2,0x660000,1);
has2.graphics.beginFill(0x660000);
has2.graphics.drawRect(160,270,30,80);
has2.graphics.endFill();
uloveligGraph.addChild(has2);
var has3:Shape = new Shape();
has3.graphics.lineStyle(2,0x660000,1);
has3.graphics.beginFill(0x660000);
has3.graphics.drawRect(230,210,30,140);
has3.graphics.endFill();
uloveligGraph.addChild(has3);
var has4:Shape = new Shape();
has4.graphics.lineStyle(2,0x660000,1);
has4.graphics.beginFill(0x660000);
has4.graphics.drawRect(300,210,30,140);
has4.graphics.endFill();
uloveligGraph.addChild(has4);
var has5:Shape = new Shape();
has5.graphics.lineStyle(2,0x660000,1);
has5.graphics.beginFill(0x660000);
has5.graphics.drawRect(370,200,30,150);
has5.graphics.endFill();
uloveligGraph.addChild(has5);
var has6:Shape = new Shape();
has6.graphics.lineStyle(2,0x660000,1);
has6.graphics.beginFill(0x660000);
has6.graphics.drawRect(440,150,30,200);
has6.graphics.endFill();
uloveligGraph.addChild(has6);
// rest of code follows as before
}
And then, it'll be as simple as removing one graph and adding another.
function klikk(evt:Event):void
{
if (cmpVelg.selectedItem.label == "Promillekjøring")
{
if (uloveligGraph.parent) uloveligGraph.parent.removeChild(uloveligGraph);
this.addChild(promilleGraph);
}
if (cmpVelg.selectedItem.label == "Ulovelig hastighet")
{
if (promilleGraph.parent) promilleGraph.parent.removeChild(promilleGraph);
this.addChild(uloveligGraph);
}
}
You never remove the children you created, use while (mySprite.numChildren > 0) mySprite.removeChildAt(0); to get rid off all cildren in a Sprite (numElements and removeElementAt if it's a SpriteVisualElement).
You can easily make this more comfortable to use. Create a function to draw your shape, like this:
function drawShape(lineThickness:Number, lineColor:uint, lineAlpha:Number, fillColor:uint, fillAlpha:Number, x:Number, y:Number, w:Number, h:Number):Shape
{
var sh:Shape = new Shape();
sh.graphics.lineStyle(lineThickness,lineColor,lineAlpha);
sh.graphics.beginFill(fillColor, fillAlpha);
sh.graphics.drawRect(x,y,w,h);
sh.graphics.endFill();
return sh;
}
And then create the shape like this:
var proen:Shape = drawShape(2,0x660000,1,0x660000.90,170,30,180);
As Vesper already answered, you can store these shapes in global variables (use const if they will not change, that's faster).

Away3d transparent bitmap Sprite3d

I'm adding some circles to away3d as sprite3ds, but for some reason they all have white backgrounds that I can't seem to remove. Anyone know what I'm missing:
var hotspot:Hotspot = e.target as Hotspot;
var spBoard:Sprite = new Sprite();
spBoard.x = circleX;
spBoard.y = circleY;
var shCircle:Shape = new Shape();
shCircle.graphics.lineStyle(2,0x000000);
shCircle.graphics.drawCircle(0,0,circleR);
shCircle.x = 0;
shCircle.y = 0;
var shFill:Shape = new Shape();
shFill.graphics.lineStyle(1,0x000000);
shFill.graphics.moveTo(0,0);
shFill.graphics.lineTo(circleR,0);
shFill.x = 0;
shFill.y = 0;
var shAngle:Shape = new Shape();
var shArrow:Shape = new Shape();
shArrow.graphics.lineStyle();
shArrow.graphics.beginFill(0x000000);
shArrow.graphics.moveTo(angleR,1);
shArrow.graphics.lineTo(angleR-5,8);
shArrow.graphics.lineTo(angleR+5,8);
shArrow.graphics.lineTo(angleR,1);
shArrow.graphics.endFill();
spBoard.addChild(shFill);
spBoard.addChild(shAngle);
spBoard.addChild(shArrow);
spBoard.addChild(shCircle);
var hotspotTimer:MovieClip = new MovieClip();
hotspotTimer.addChild(spBoard);
var bounds:Rectangle = hotspotTimer.getBounds(hotspotTimer);
var bitmapData : BitmapData = new BitmapData(512, 512);
bitmapData.draw(hotspotTimer);
var bitmapPointsTexture:BitmapTexture = new BitmapTexture(bitmapData);
var _pointsMaterial:TextureMaterial = new TextureMaterial(bitmapPointsTexture);
var inworldHotspotTimer:Sprite3D = new Sprite3D(_pointsMaterial,bitmapData.width,bitmapData.height);
inworldHotspotTimer.x = hotspot.x;
inworldHotspotTimer.y = hotspot.y;
inworldHotspotTimer.z = hotspot.z;
scene.addChild(inworldHotspotTimer);
}
I've seen in blog posts such as this
http://www.allforthecode.co.uk/aftc/forum/user/modules/forum/article.php?index=6&subindex=4&aid=315
On how they do it, but they're using an older version with the BitmapMaterial removed.
Change the line that declares the bitmapdata to this:
var bitmapData : BitmapData = new BitmapData(512, 512, true, 0x00808080);
If you don't fill the bitmap with a color that has alpha of 0, you'll get the borders in the texture.

How to apply color transform but leave the drop shadow in the same color

I have a bitmap in as3. I want to tint the color of the bitmap, but also I want to have black drop shadow all the time.
How to achieve this?
var bitmap:Bitmap = new Assets.bitmap();
var dropShadow = new DropShadowFilter();
bitmap.filters = new Array(dropShadow);
var colorTransform = new ColorTransform();
colorTransform.color = 0xFF00FF;
bitmap.tranform.colorTransform = colorTransform;
Thank you
You can achieve this with nesting.
Create a Sprite, add the bitmap as a child of that sprite, then add the drop shadow to the sprite and the color transform to the bitmap (as before).
var bitmap:Bitmap = new Assets.bitmap();
var container:Sprite = new Sprite();
container.addChild(bitmap);
var dropShadow = new DropShadowFilter();
container.filters = new Array(dropShadow);
var colorTransform = new ColorTransform();
colorTransform.color = 0xFF00FF;
bitmap.tranform.colorTransform = colorTransform;
addChild(container); //wherever you were adding the bitmap, add the container instead.

Issues with BitmapData of a MovieClip with rotationY applied to it

So I have a simple file right now that eventually will take a movieclip and save it as an image. I am currently rotating the clip's y by 45 to give it kind of a 3D look and adding it back to the stage. I've tried googling and a couple different things, but I can't quite get it to work. The first thing I tried was getting the BitmapData of the movieclip I rotated. That flattened the clip:
test_mc.response_mc.rotationY = 45;
var mc:MovieClip = test_mc.response_mc;
var bmp:BitmapData = new BitmapData(mc.width, mc.height);
bmp.draw(mc);
var output:Bitmap = new Bitmap(bmp);
output.x = 270;
output.y = 191;
addChild(output);
The next thing I tried was getting the parent clip's BD. That gave it an angle... just the wrong one:
(same code as above with this line change)
var mc:MovieClip = test_mc;
Any thoughts here would be nice. I tried doing stuff with matrices, but had no luck. I also have images... just can't post them yet :(
Something else I've tried with no luck:
var target:DisplayObject = test_mc as DisplayObject;
var targetTransform:Matrix = target.transform.concatenatedMatrix;
var targetGlobalBounds:Rectangle = target.getBounds(target.stage);
var targetGlobalPos:Point = target.localToGlobal(new Point());
var targetOriginOffset:Point = new Point(targetGlobalPos.x - targetGlobalBounds.left, targetGlobalPos.y - targetGlobalBounds.top);
targetTransform.tx = targetOriginOffset.x;
targetTransform.ty = targetOriginOffset.y;
var cloneData:BitmapData = new BitmapData(targetGlobalBounds.width, targetGlobalBounds.height, true, 0x00000000);
cloneData.draw(target, targetTransform);
var output:Bitmap = new Bitmap(cloneData);
**Another update**
So hopefully this will help a little. I was able to recreate what I was doing using Matrix3D.
test_mc.response_mc.rotationY = 45;
var matrix:Matrix3D = new Matrix3D();
matrix.prependRotation(45, Vector3D.Y_AXIS);
test2_mc.response_mc.transform.matrix3D = matrix;
test2_mc.response_mc.transform.matrix3D.appendTranslation(0, 0, 0);
And I've come closer to getting the bitmap to look correct (thank to a Mike Chambers blog).
var mcOffset:Matrix3D = test2_mc.response_mc.transform.matrix3D;
var rawMatrixData:Vector.<Number> = mcOffset.rawData;
var globalBounds:Rectangle = test2_mc.response_mc.getBounds(test2_mc);
var matrix:Matrix = new Matrix();
matrix.a = rawMatrixData[0];
matrix.c = rawMatrixData[1];
matrix.tx = test2_mc.response_mc.x - globalBounds.x;
matrix.b = rawMatrixData[4];
matrix.d = rawMatrixData[5];
matrix.ty = test2_mc.response_mc.y - globalBounds.y;
var bmp:BitmapData = new BitmapData(150, test2_mc.height);
test2_mc.response_mc.transform.matrix3D = null;
bmp.draw(test2_mc.response_mc, matrix);
test2_mc.response_mc.transform.matrix3D = mcOffset;
var output:Bitmap = new Bitmap(bmp);
Well I took it a step further back and went to the stage. For whatever reason trying to draw the parent (test_mc) of the rotated movie clip (response_mc) WON'T work, however drawing the stage and setting the bounds to the area of the parent DOES work. Here's my code (which is sadly very simple):
var bmp:BitmapData = new BitmapData(test_mc.width, test_mc.height);
bmp.draw(stage.getChildAt(0), new Matrix(1, 0, 0, 1, -test_mc.x, -test_mc.y));
var output:Bitmap = new Bitmap(bmp);

Actionscripts 3 Clone MovieClip

How do we clone a copy of an "Instance name"? Thanks guys
//The test_close is an instance name which I drew on the canvas.
var cloneMe:MovieClip = new MovieClip();
cloneMe.graphics.copyFrom(test_clone.graphics); //here is my clone codes
addChild(cloneMe);
trace(cloneMe.getBounds(cloneMe));
If you simply need a copy of the object that has been drawn, use the BitmapData draw method.
var bmd:BitmapData = new BitmapData(cloneMe.width , cloneMe.height );
bmd.draw( cloneMe);
var bm:Bitmap = new Bitmap(bmd);
// not relevant, simply shifting the new Bitmap so that it is visible
bm.x = 10;
bm.y = 10;
addChild( bm );