3

我正在尝试绘制一个会产生视觉时钟的“倒计时”圆圈,但不喜欢最终的形状,因为它不平滑。当变量“numberOfSides”足够大时,下面的代码会绘制并填充一系列近似圆形的三角形,但这既低效又会产生丑陋的“圆形”。我想做的是在线段上绘制一系列弧线,但我不知道该怎么做。任何人都可以在正确的方向上给我一个刺激吗?

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" minWidth="955" minHeight="600" frameRate="100" creationComplete="init()">
<mx:Script>
    <![CDATA[
        private var numberOfSides:int = 10;
        private var angle:Number = 0;
        private var lineLength:int = 100;
        private var xStartingPos:int = 300;
        private var yStartingPos:int = 300;
        private var i:int = 90;//Start the drawing  at 0 to 360;
        private var speed:int = 100;
        private var timer:Timer  
        private function init():void{
            //uic.graphics.lineStyle(1);
            uic.graphics.moveTo(xStartingPos,yStartingPos);
            uic.graphics.beginFill(0xffff00);
            timer = new Timer(speed, numberOfSides + 1);
            timer.addEventListener(TimerEvent.TIMER,cont);
            timer.start()
        }
        private function cont(event:TimerEvent):void{
                angle = (Math.PI / numberOfSides * 2) * i;
                var xAngle:Number = Math.sin(angle);                 
                var yAngle:Number = Math.cos(angle);
                var xResult:int = xAngle * lineLength;
                var yResult:int = yAngle * lineLength;
                uic.graphics.lineTo(xStartingPos + xResult, yStartingPos + (yResult*-1));
                i++
        }
    ]]>
</mx:Script>
<mx:Canvas  id="uic"/>
</mx:Application>
4

2 回答 2

2

这可以通过使用以下方法绘制楔形来完成nl.funkymonkey.drawing.DrawingShapes

楔形-1 楔形 2 楔形 3 楔形 4 楔形 5

绘制楔形函数:

public static function drawWedge(target:Graphics, x:Number, y:Number, radius:Number, arc:Number, startAngle:Number=0, yRadius:Number=0):void
{
    if (yRadius == 0)
        yRadius = radius;

    target.moveTo(x, y);

    var segAngle:Number, theta:Number, angle:Number, angleMid:Number, segs:Number, ax:Number, ay:Number, bx:Number, by:Number, cx:Number, cy:Number;

    if (Math.abs(arc) > 360)
        arc = 360;

    segs = Math.ceil(Math.abs(arc) / 45);
    segAngle = arc / segs;
    theta = -(segAngle / 180) * Math.PI;
    angle = -(startAngle / 180) * Math.PI;
    if (segs > 0)
    {
        ax = x + Math.cos(startAngle / 180 * Math.PI) * radius;
        ay = y + Math.sin(-startAngle / 180 * Math.PI) * yRadius;
        target.lineTo(ax, ay);
        for (var i:int = 0; i < segs; ++i)
        {
            angle += theta;
            angleMid = angle - (theta / 2);
            bx = x + Math.cos(angle) * radius;
            by = y + Math.sin(angle) * yRadius;
            cx = x + Math.cos(angleMid) * (radius / Math.cos(theta / 2));
            cy = y + Math.sin(angleMid) * (yRadius / Math.cos(theta / 2));
            target.curveTo(cx, cy, bx, by);
        }
        target.lineTo(x, y);
    }
}

示例实现,动画倒数计时器:

var value:Number = 0;

addEventListener(Event.ENTER_FRAME, frameHandler);

function frameHandler(event:Event):void
{
    var g:Graphics = graphics;
    g.clear();

    value += 0.01;

    g.lineStyle(1, 0x0000ff, 0.25);
    g.beginFill(0x123456, 0.25);
    drawWedge(g, 100, 100, 50, (360 * value) % 360);
    g.endFill();
}

可以使用任何图形线条样式或填充;或者,填充物可以用作遮罩。

于 2013-06-11T03:53:25.663 回答
0

我在网上找到的另一段代码:

http://flassari.is/2009/11/pie-mask-in-as3/

将其更改为:

var circleToMask:Sprite = new Sprite();
circleToMask.graphics.beginFill(0x004BA5DC); // color circle 0x00RRGGBB
circleToMask.graphics.drawCircle(0, 0, 50);
circleToMask.graphics.endFill();
addChildAt(circleToMask, 0);
var circleMask:Sprite = new Sprite();
circleToMask.x = (circleMask.x = 50);
circleToMask.y = (circleMask.y = 50);
circleToMask.mask = circleMask;
addChild(circleMask);

// inner circle
var circleTopMask:Sprite = new Sprite();
circleTopMask.graphics.beginFill(0x00FFFFFF); // color inner circle
circleTopMask.graphics.drawCircle(0, 0, 25);
circleTopMask.graphics.endFill();
addChild(circleTopMask);
circleTopMask.x = 50;
circleTopMask.y = 50;

// textfield in the center
var myFormat:TextFormat = new TextFormat();
myFormat.size = 18;
var myText:TextField = new TextField();
myText.defaultTextFormat = myFormat;
myText.text = "0%";
myText.autoSize = TextFieldAutoSize.CENTER;
myText.y = 50 - (myText.height/2);
addChild(myText);

var percentage:Number = 0;
var tper:Number = 0;

addEventListener(Event.ENTER_FRAME, function (_arg1:Event):void{
    graphics.clear();
    // Percentage should be between 0 and 1
    tper = percentage < 0 ? 0 : (percentage > 1 ? 1 : percentage);
    // Draw the masked circle
    circleMask.graphics.clear();
    circleMask.graphics.beginFill(0);
    drawPieMask(circleMask.graphics, tper, 50, 0, 0, (-(Math.PI) / 2), 3);
    circleMask.graphics.endFill();
    // Increase percentage with margins so it appears to stop for a short while
    percentage = (percentage + 0.01);
    if (percentage > 1){
        percentage = 0;
    }

    myText.text = ((percentage*100).toFixed(0))+"%";

})

function drawPieMask(graphics:Graphics, percentage:Number, radius:Number = 50, x:Number = 0, y:Number = 0, rotation:Number = 0, sides:int = 6):void {
    // graphics should have its beginFill function already called by now
    graphics.moveTo(x, y);
    if (sides < 3) sides = 3; // 3 sides minimum
    // Increase the length of the radius to cover the whole target
    radius /= Math.cos(1/sides * Math.PI);
    // Shortcut function
    var lineToRadians:Function = function(rads:Number):void {
        graphics.lineTo(Math.cos(rads) * radius + x, Math.sin(rads) * radius + y);
    };
    // Find how many sides we have to draw
    var sidesToDraw:int = Math.floor(percentage * sides);
    for (var i:int = 0; i <= sidesToDraw; i++)
        lineToRadians((i / sides) * (Math.PI * 2) + rotation);
    // Draw the last fractioned side
    if (percentage * sides != sidesToDraw)
        lineToRadians(percentage * (Math.PI * 2) + rotation);
}        

生成的 FLA 的大小应为 100 x 100 像素。

导致:

截屏

于 2013-12-09T14:38:00.180 回答