Search code examples
actionscript-3graphicsadobe-animate

Use beginBitmapFill with existing movieclip/shape? (Animate CC)


All the tutorials for using beginBitmapFill seem to center around dynamically drawing an object. Is it possible to simply apply a bitmap fill to an existing shape that's inside a movieclip? I know I can do this manually by selecting the shape and selecting a bitmap in the Color panel.. but is it possible to do it with code? This is what I'm trying and it's not giving errors, but it's also not working:

grl.tops.shapes.graphics.beginBitmapFill(new cubepattern(), null, true, false);

Solution

  • As others have commented, you can use readGraphicsData and drawGraphicsData respectively. It's even not over-complicated. Simply loop through the IGraphicsData of your desired shape, stop as soon as you've found an instance of the GraphicsBitmapFill class, create a new instance with another BitmapFill and finally apply the changes to the original shape.

    Well, a picture is worth a thousand words. Here's an example. This might seem a bit long but there's just a whole lot of code to prepare a shape and load images to be used as bitmap fills.

    Set your eyes on the process() function.

    package
    {
        import flash.display.Sprite;
        import flash.display.Shape;
        import flash.display.Graphics;
        import flash.display.Loader
        import flash.display.LoaderInfo;
        import flash.display.IGraphicsData;
        import flash.display.GraphicsBitmapFill;
        import flash.display.Bitmap;
        import flash.display.BitmapData;
        import flash.events.Event;
        import flash.net.URLRequest;
        import flash.utils.getQualifiedClassName;
    
        public class Main extends Sprite
        {
            private var bitmapData1:BitmapData;
            private var bitmapData2:BitmapData;
            private var masterSprite:Sprite = new Sprite();
            private var texturesLoaded:int = 0;
            private var loader:Loader = new Loader();
    
            public function Main():void
            {
                if (stage)
                    init();
                else
                    addEventListener(Event.ADDED_TO_STAGE, init);
            }
    
            private function init(e:Event = null):void
            {
                removeEventListener(Event.ADDED_TO_STAGE, init);
                loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
                loader.load(new URLRequest("textureA.jpg"));
                addChild(masterSprite);
                masterSprite.x = masterSprite.y = 200;
            }
    
            private function onComplete(event:Event):void
            {
                switch (texturesLoaded)
                {
                    case 0: 
                        bitmapData1 = Bitmap(LoaderInfo(event.target).content).bitmapData;
                        loader.load(new URLRequest("textureB.jpg"));
                        break;
                    case 1: 
                        bitmapData2 = Bitmap(LoaderInfo(event.target).content).bitmapData;
                        loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, onComplete);
                        drawStar();
                        process();
                }
                texturesLoaded++;
            }
    
            private function process():void
            {
                var tempShape:Shape = Shape(masterSprite.getChildAt(0));
    
                var graphicsData:Vector.<IGraphicsData> = tempShape.graphics.readGraphicsData();
                for (var a:int = 0; a < graphicsData.length; a++)
                {
                    if (getQualifiedClassName(graphicsData[a]) == "flash.display::GraphicsBitmapFill")
                    {
                        var bitmapFill:GraphicsBitmapFill = new GraphicsBitmapFill(bitmapData2);
                        graphicsData[a] = bitmapFill; break;
                    }
                }
                tempShape.graphics.drawGraphicsData(graphicsData);
            }
    
            private function drawStar():void
            {
                var angles:Array = new Array(0, 36, 72, 108, 144, 180, 216, 252, 288, 324, 360);
                var innerRadius:int = 40;
                var outerRadius:int = 80;
                var shape:Shape = new Shape();
                shape.graphics.beginBitmapFill(bitmapData1);
                shape.graphics.moveTo(0 + Math.cos(angles[a] * (Math.PI / 180)) * outerRadius, 0 + Math.sin(angles[a] * (Math.PI / 180)) * outerRadius);
                for (var a:int = 0; a < angles.length; a++)
                {
                    angles[a] -= 90;
                    if (a % 2 == 0)
                    {
                        shape.graphics.lineTo(0 + Math.cos(angles[a] * (Math.PI / 180)) * outerRadius, 0 + Math.sin(angles[a] * (Math.PI / 180)) * outerRadius);
                    }
                    else
                    {
                        shape.graphics.lineTo(0 + Math.cos(angles[a] * (Math.PI / 180)) * innerRadius, 0 + Math.sin(angles[a] * (Math.PI / 180)) * innerRadius);
                    }
                }
                shape.graphics.endFill();
                masterSprite.addChild(shape);
            }
        }
    }