如何在图形中绘制两个相交的圆孔?

时间:2011-10-25 13:19:00

标签: flash

我需要内部有两个圆孔的绘制矩形。问题在于圈子拦截。我希望他们一起加入并从背景中切割,但他们似乎是异和的:

enter image description here enter image description here

首先我尝试了drawRectDrawCircle

graphics.beginFill(0, 0.5);
graphics.drawRect(0, 0, width, height);
graphics.drawCircle(width/2, height/2, 50);
graphics.drawCircle(width/2-30, height/2-30, 50);
graphics.endFill();

然后我切换到drawPath,但也没有运气:

graphics.beginFill(0, 0.5);
var c1:Object = getCirclePath(width/2-30, height/2-30, 50);
var c2:Object = getCirclePath(width/2, height/2, 50);

graphics.drawPath(new <int>[
        GraphicsPathCommand.MOVE_TO, GraphicsPathCommand.LINE_TO,
        GraphicsPathCommand.LINE_TO, GraphicsPathCommand.LINE_TO,
        GraphicsPathCommand.LINE_TO],
    new <Number>[0, 0, myCanvas.width, 0, myCanvas.width, myCanvas.height,
        0, myCanvas.height, 0, 0]);

myCanvas.graphics.drawPath(c1.commands, c1.data);
myCanvas.graphics.drawPath(c2.commands, c2.data);

graphics.endFill();

此处getCirclePath返回带有点的对象,以绘制看起来像圆的多边形。我也尝试了GraphicsPathWinding常量的不同组合,但没有运气。

如何在图形中绘制两个相交的圆孔?

2 个答案:

答案 0 :(得分:3)

如果您想要绘制多个圆圈,而没有相互交叉的路径“异或” - 那么您应该为每个绘制的形状beginFill(...)endFill()

我还没有测试过,但这是我猜测正确渲染重叠的形状。

- 编辑 -

链接到演示:http://bit.ly/vBW1ag

如何使用blendmodes?

尝试将场景设置为:

  • 您的rect和圆圈的容器的blendMode为BlendMode.LAYER;
  • 您的矩形是容器的子项;
  • 您创建的圆圈是容器的子项,超出矩形,并使其blendMode BlendMode.ERASE;

一旦开始补间,你就应该获得动画效果。

请参阅下面的示例(您可以将其投入新项目以查看其运行情况)

package 
{
    import flash.display.BlendMode;
    import flash.display.Graphics;
    import flash.display.Shape;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.utils.getTimer;

    public class Main extends Sprite 
    {
    private var _rect:Shape;
    private var _circles:Array;
    private var _container:Sprite;
    private var _subContainer:Sprite;
    private var _numOfCircles:int = 2;

    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);
        // entry point

        createContainers();
        createRect( 256, 256 );
        createCircles( 40 );

        centerSetup();

        stage.addEventListener(Event.ENTER_FRAME, onUpdate);
    }

    private function createContainers():void 
    {
        _container =    new Sprite();
        _container.blendMode =  BlendMode.LAYER;

        addChild(_container);

        _subContainer = new Sprite();
        _subContainer.blendMode =   BlendMode.ERASE;
        _container.addChild(_subContainer);
    }

    private function createRect(pWidth:Number, pHeight:Number):void 
    {
        _rect = new Shape();

        var g:Graphics =    _rect.graphics;
        g.beginFill(0, 0.5);
        g.drawRect(0, 0, pWidth, pHeight);
        g.endFill();

        /*
         * The canvas that must have the "hole" punched through
         * MUST appear as the first child in the DisplayList.
         */
        _container.addChildAt( _rect, 0 );
    }


    private function createCircles( pRadius:Number ):void 
    {
        var circle:Shape;
        var g:Graphics;

        _circles =  [];

        for (var n:int = _numOfCircles; --n >= 0; ) {
            circle =    new Shape();
            g =         circle.graphics;
            g.beginFill(0xffffff, 1);
            g.drawCircle(0, 0, pRadius);
            g.endFill();


            _subContainer.addChild( circle );
            _circles.push( circle );
        }
    }


    private function centerSetup():void 
    {
        _container.x =  (stage.stageWidth - _rect.width) * .5;
        _container.y =  (stage.stageHeight - _rect.height) * .5;
    }

    private function onUpdate(e:Event):void 
    {
        var circle:Shape;
        var currentTime:Number =    getTimer() * .001;
        var amplitude:Number =      50;
        var direction:int;

        var halfWidth:int =     _rect.width * .5;
        var halfHeight:int =    _rect.height * .5;

        for (var n:int = _numOfCircles; --n >= 0; ) {
            circle =    _circles[n] as Shape;
            direction = (n % 2) == 0 ? 1 : -1;
            circle.x =  halfWidth + Math.cos(currentTime*direction + n) * amplitude;
            circle.y =  halfHeight + Math.sin(currentTime*direction + n) * amplitude;
        }
    }

}

}

答案 1 :(得分:0)

在Flash中,默认的缠绕规则甚至是奇数。

http://help.adobe.com/en_US/as3/dev/WS1EE3740D-F65C-43bf-9B12-74E34D7D1CBE.html

在第二个示例中,基于GraphicsPathWinding将绕组添加到drawPath:

import flash.display.GraphicsPathWinding;

GraphicsPathWinding.NON_ZERO

所以,这将成为:

graphics.drawPath(new <int>[/*...*/], new <Number>[/*...*/], GraphicsPathWinding.NON_ZERO);