multiverse
multiverse

Reputation: 483

AS3 Fill Color inside line by pen

I was trying to make a flash app with AS3 where I can draw line with pen tool with different colors , also fill the shapes on an image with different colors, now I have went through various tutorials and achieved it, however in the end I am faced with 2 problems that I am unable to solve even after 3 days of efforts:

  1. How can I fill color inside the shapes formed by using the pen tool, say if I draw a rough circle using pen tool and then I try and fill it with green, how can I detect MovieClips which I need to fill.
  2. When I draw lines over shapes and then try and fill the shapes, the shapes gets filled but the lines still appear on top of the shapes filled with color.

You can get a better idea of what I have achieved by visiting this link, click the pen symbol and paint bucket symbol to see how it works.

Below is my code for pen tool and fill color:

I draw a sprite add an image and then use the property to detect color to draw a line of color I choose, followed by code to fill color where I divide the image in various MovieClips and then make then into one and detect if mouse is clicked on which clip and fill it with selected color.

import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.MouseEvent;


bucbut.addEventListener(MouseEvent.CLICK,nClick0PC);



/////////////pentool code --------
convertToBMD();
pbut.addEventListener(MouseEvent.CLICK,nClick0P);



function nClick0P(event:MouseEvent):void{

spBoard.addEventListener(MouseEvent.ROLL_OUT,boardOut);

spBoard.addEventListener(MouseEvent.MOUSE_MOVE,boardMove);

spBoard.addEventListener(MouseEvent.MOUSE_DOWN,boardDown);

spBoard.addEventListener(MouseEvent.MOUSE_UP,boardUp);


}
var spBoard:Sprite=new Sprite(); 

this.addChildAt(spBoard,0);
spBoard.x=20;

spBoard.y=100;
var owl2:owl;
owl2 = new owl();
owl2.name="owl1";
spBoard.addChildAt(owl2,0);
owl2.x=315;

owl2.y=180;


var shDrawing:MovieClip = new MovieClip();
//var shDrawing:Shape=new Shape();
spBoard.addChild(shDrawing);
//spBoard.addChildAt(shDrawing,1);
function nClick0PC(event:MouseEvent):void{

    owl2.addEventListener(MouseEvent.CLICK,on_owl_click);
}



var doDraw:Boolean=false;

var lineSize:Number=10;

var currentColor:Number;


spBoard.graphics.lineStyle(1,0x000000);

spBoard.graphics.beginFill(0xFFFFFF);

spBoard.graphics.drawRect(0,0,602,330);

spBoard.graphics.endFill();

spBoard.filters = [ new DropShadowFilter() ];







function boardOut(e:MouseEvent):void {

            doDraw=false;

    }


function boardDown(e:MouseEvent):void {

            doDraw=true;

            trace(activeColor);

            shDrawing.graphics.lineStyle(lineSize,activeColor);

            shDrawing.graphics.endFill(); 

            shDrawing.graphics.moveTo(shDrawing.mouseX,shDrawing.mouseY);



    }

function boardUp(e:MouseEvent):void {

            doDraw=false;

    }

function boardMove(e:MouseEvent):void {

            var curX:Number=shDrawing.mouseX;

            var curY:Number=shDrawing.mouseY;


            if(doDraw && checkCoords(curX,curY)){

                shDrawing.graphics.lineTo(curX,curY);

                e.updateAfterEvent();

            }

    }




    function checkCoords(a:Number,b:Number):Boolean {

    if(a>=605-lineSize/2 || a<=lineSize/2 || b>=311-lineSize/2 || b<=lineSize/2){

        return false;
    } 

    else {

        return true;
    }

}



/////////////---------------------color picker
colors.addEventListener(MouseEvent.MOUSE_UP, chooseColor);
var pixelValue:uint;
        var activeColor:uint = 0x000000;
        var ct:ColorTransform = new ColorTransform();
var colorsBmd:BitmapData;
        function convertToBMD():void
        {
            colorsBmd = new BitmapData(colors.width,colors.height);
            colorsBmd.draw(colors);
        }


        function chooseColor(e:MouseEvent):void
        {
            pixelValue = colorsBmd.getPixel(colors.mouseX,colors.mouseY);
            activeColor = pixelValue;//uint can be RGB!

            ct.color = activeColor;
            //shapeSize.transform.colorTransform = ct;
        }

        ////////////////////========================================Fill color



        function on_owl_click(e:MouseEvent):void {


            for (var i:int = 0; i < owl2.numChildren; i++) {


                if (owl2.getChildAt(i).hitTestPoint(mouseX,mouseY,true)) {




                    trace(owl2.getChildAt(i).name);
                                        owl2.getChildAt(i).transform.colorTransform= ct;

                }
            }
        }

Upvotes: 0

Views: 1019

Answers (1)

Daniil Subbotin
Daniil Subbotin

Reputation: 6718

I deleted a lot of your code and left this:

convertToBMD();
colors.addEventListener(MouseEvent.MOUSE_UP, chooseColor);
var activeColor: uint = 0x000000;
var colorsBmd: BitmapData;
function convertToBMD(): void
{
    colorsBmd = new BitmapData(colors.width, colors.height);
    colorsBmd.draw(colors);
}
function chooseColor(e: MouseEvent): void
{
    var pixelValue:uint = colorsBmd.getPixel(colors.mouseX, colors.mouseY);
    activeColor = pixelValue; //uint can be RGB!
}

Also I removed an owl at the stage. Download my FLA to see changes.

Next. I added two canvases.

var canvasData:BitmapData = new BitmapData(650, 437, false, 0xEFEFEF);
var canvas:Bitmap = new Bitmap(canvasData);
canvas.x = 0;
canvas.y = 102;
addChild(canvas);

var penCanvas:Shape = new Shape();
penCanvas.x = canvas.x;
penCanvas.y = canvas.y;

You can read about Bitmap and BitmapData here. First canvas it's a raster image. Second canvas it's a Shape, so you can use moveTo and lineTo methods to draw with a pencil.

Next. In library i found an owl image and export it to code. owl If not understand, I can explain more detailed.

Next. Registration event handlers.

bucbut.addEventListener(MouseEvent.CLICK, clickBucket);
pbut.addEventListener(MouseEvent.CLICK, clickPen);

function clickBucket(event:MouseEvent):void
{
    stage.removeEventListener(MouseEvent.MOUSE_DOWN, canvasDown);
    stage.addEventListener(MouseEvent.CLICK, clickOnCanvas);
}

function clickPen(event:MouseEvent):void
{
    stage.addEventListener(MouseEvent.MOUSE_DOWN, canvasDown);
    stage.removeEventListener(MouseEvent.CLICK, clickOnCanvas);
}

Let's see at clickOnCanvas method:

function clickOnCanvas(event:MouseEvent):void
{
    // If we click at the canvas
    if (canvas.hitTestPoint(mouseX,mouseY))
    {
        canvasData.floodFill(canvas.mouseX, canvas.mouseY,activeColor);
    }
}

About floodFill you can read here.

And the last three methods used to draw by pen.

function canvasDown(event:MouseEvent):void
{
    penCanvas.graphics.lineStyle(10, activeColor);
    penCanvas.graphics.moveTo(penCanvas.mouseX, penCanvas.mouseY);

    // only when mouse button is down we register two handlers, one for move and another for mouse up
    stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMove);
    stage.addEventListener(MouseEvent.MOUSE_UP, mouseUp);
}

function mouseMove(event:MouseEvent):void
{
    // when mouse is moving we are drawing line
    penCanvas.graphics.lineTo(penCanvas.mouseX, penCanvas.mouseY);
    // As I said earlier canvasData it's a raster image. So we copy penCanvas and paste to canvasData.
    canvasData.draw(penCanvas);

    // For a smoother drawing
    event.updateAfterEvent();
}

function mouseUp(event:MouseEvent):void
{
    stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMove);
    stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUp);
}

That's all!

Here you can download sources.

Upvotes: 3

Related Questions