【问题标题】:AS3 Fill Color inside line by penAS3 用笔在行内填充颜色
【发布时间】:2015-02-16 10:00:55
【问题描述】:

我正在尝试使用 AS3 制作一个 Flash 应用程序,我可以使用钢笔工具绘制不同颜色的线条,还可以用不同颜色填充图像上的形状,现在我已经完成了各种教程并实现了它,但是在最后,我面临 2 个问题,即使经过 3 天的努力,我也无法解决:

  1. 如何在使用钢笔工具形成的形状内填充颜色, 说如果我使用钢笔工具画一个粗略的圆圈然后我尝试填充 它是绿色的,我怎样才能检测到我需要填写的MovieClips。
  2. 当我在形状上画线然后尝试填充形状时, 形状被填充,但线条仍然出现在形状的顶部 充满色彩。

您可以通过访问this link 更好地了解我所取得的成就,单击钢笔符号和油漆桶符号以查看其工作原理。

以下是我的钢笔工具和填充颜色代码:

我绘制一个精灵添加一个图像,然后使用属性检测颜色来绘制一条我选择的颜色线,然后是填充颜色的代码,我将图像划分为各种MovieClips,然后再合成一个并检测鼠标是否点击了哪个剪辑并用选定的颜色填充它。

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;

                }
            }
        }

【问题讨论】:

  • 我看到猫头鹰是BitmapData。填充操作是BitmapData.floodfill() 方法。因此,您需要致电 BitmapData.draw() 将您的笔画添加到该 BitmapData。
  • 嗨 subdan,实际上 owl 是一个影片剪辑,其中包含几个影片剪辑,所以当我单击 owl 时,我可以检测到其中的哪个影片剪辑已被单击,并且我可以对影片剪辑进行颜色转换,问题是,我如何在使用钢笔工具绘制的形状内填充颜色以及如何使填充的颜色出现在绘制的线条上方,如果在猫头鹰脸上画了一条线,我填充颜色,线条仍然显示,我可以在该特定区域填写行吗...提前谢谢...。
  • @subdan ,您能指导我在哪里进行更改吗?到目前为止我编写的代码仅在上面......谢谢
  • 你能提供一个FLA文件吗?
  • 简而言之。你需要一个画布(位图)。在画布上绘制一只猫头鹰 (BitmapData.copyPixels)。填充动作(Paint bucket)它是 BitmapData 的一个 floodFill 方法。绘制动作(铅笔)它是一个 BitmapData.draw 方法。

标签: actionscript-3 flash


【解决方案1】:

我删除了你的很多代码并留下了这个:

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!
}

我还移除了舞台上的一只猫头鹰。下载我的FLA 以查看更改。

接下来。我添加了两个画布。

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;

您可以阅读有关 Bitmap 和 BitmapData here 的信息。 第一个画布是光栅图像。第二个画布是一个形状,因此您可以使用 moveTo 和 lineTo 方法用铅笔绘制。

接下来。在库中,我找到了一个猫头鹰图像并将其导出为代码。 如果不明白,我可以解释的更详细。

接下来。注册事件处理程序。

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);
}

让我们看看clickOnCanvas方法:

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

关于floodFill你可以阅读here

还有最后三种用钢笔画的方法。

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);
}

就是这样!

Here你可以下载源码。

【讨论】:

  • 您好 subdan 非常感谢您的帮助,您能否再次检查 fla 链接和源链接,我尝试下载它但它不起作用,我现在正在尝试使用您的代码做出改变,如果我能得到 fla,我可能会看到我错在哪里......再次非常感谢......
  • @multiverse,您应该在canvasData.draw(penCanvas); 之后添加此代码canvasData.copyPixels(owlData,new Rectangle(0,0,owlData.width,owlData.height), new Point(150, 60));。这是96行。如果你愿意,我可以解释我为什么这样做。
  • @multiverse 在mouseUp 函数中添加penCanvas.graphics.clear();
  • 这是由于平滑造成的。 floodFill 只会填充一种颜色。画线有几种阴影。见subdan.ru/work/12.png 只会填充黑色。灰色未填充。我帮不了你。
  • 我建议你使用this library。不存在这样的问题。我总是用它。
猜你喜欢
  • 1970-01-01
  • 2016-12-11
  • 1970-01-01
  • 2012-02-14
  • 1970-01-01
  • 1970-01-01
  • 2021-05-16
  • 2016-08-02
相关资源
最近更新 更多