0

円形の進行状況バーを表示しようとしていますが、行き詰っています。

色付きの円を描くのに問題はありませんが、中心の色を削除する方法と、不足しているパーセントを表す小さな部分を削除する方法がわかりません。

実際の解決策は、5% ごとに置き換える背景の画像を使用することです。うまくいきますが、重くてぎくしゃくしています。円の色を変更する必要がある場合は、20 枚の絵をすべて描き直さなければなりません。

この「進行円」を動的に描画できるソリューションはありますか?

4

2 に答える 2

3

これは、あなたが思っているよりもずっと複雑です。

円に穴を開けるには、アルファ マスクを使用する必要があります。適切に行う方法についてのドキュメントがほとんどないため、これを理解するのは大変ですが、理解すれば比較的簡単です。「レイヤー」のを作成し、true に設定する必要がありGroupます。次に、を使用してシェイプを作成し、「erase」と cacheAsBitmap を true に設定してグループ (その下にある必要があります) を作成します。そのグループで、親シェイプに穴を開けるために使用するシェイプを描画します。blendModecacheAsBitmapEllipseblendMode

例:

<s:Group cacheAsBitmap="true" blendMode="layer">
    <s:Ellipse id="background" width="84" height="84" >
        <s:fill>
            <s:SolidColor color="0"/>
        </s:fill>
    </s:Ellipse>

    <s:Group id="backgroundMask" horizontalCenter="0" verticalCenter="0" blendMode="erase" cacheAsBitmap="true">
        <s:Ellipse width="64" height="64" >
            <s:fill>
                <s:SolidColor color="0"/>
            </s:fill>
        </s:Ellipse>
    </s:Group>
</s:Group>

これは、最近作成したアプリから直接取得したものなので、動作することを確認できます。これにより、中心に 64 ピクセルの穴がある直径 84 ピクセルの円が作成されます。

編集: RIAStar がコメントで指摘したように、実際には、私の複雑な方法ではなく、ストロークでこれを行うことができます。

彼のコメントから:

<s:Ellipse width="74" height="74">
    <s:stroke>
    <s:SolidColorStroke weight="10"/>
    </s:stroke>
</s:Ellipse>

実際の進行を行うには、少しトリグを行う必要があります。残念ながら、ベジェパスなしでこれを行う方法はありません(私が知っていることです)。したがって、基本的にPathオブジェクトを作成し、進行状況の更新時にそのdata. これが実際の円のマスクになります。

象限も描く必要があるので、さらに複雑です。基本的に、上中央から開始し、円の中心まで下に描き、進行中の現在のポイントまで描き、次にその四分円の隅に描き、次に前の各隅に描き、最後に上中央に戻ります。

実際のパスを描画するためのコードを提供することはできません (どこにでもある一般的なコードではなく、私の NDA ではそうすることができません) が、現在の進行状況の円のポイントを取得する方法を示すことはできます。円の属性によっては、ポイントを埋める必要があるかもしれませんが、いずれにせよ、これは作業の開始点としては適切です。

var halfHeight:Number = this.background.height / 2;
var halfWidth:Number = this.background.width / 2;
var angle:Number = -this.progress * 2 * Math.PI - Math.PI / 2; (uses negative progress to indicate counter-clockwise direction)
var pointOnCircle:Point = new Point(halfWidth * Math.cos( angle ) + halfWidth, halfWidth * Math.sin( angle ) + halfWidth);

pointOnCircleは、上に描かれた円の外側の端に配置する必要があります。this.progressは 0 ~ 1 の数値です。必ずその範囲に制限してください。私の記憶が正しければ、これらの境界を超えるとこれが壊れます。

うまくいけば、それは役に立ちます。繰り返しますが、これ以上のものをお見せすることはできませんが、始めるには十分すぎるはずです

于 2013-10-02T18:15:54.727 に答える
1

ありがとうございます。

最後に、 http://flassari.is/2009/11/pie-mask-in-as3/から Josh のコードとスクリプトの両方を入手しました。

flassari のコードを使用して円を描画および更新し (元に戻すモードで 100% から 0% に編集するように編集)、円の中心に穴をあける Josh の方法を使用しました。

使用したメインコードは次のとおりです。

private function init():void
{
    // Store sprites
    var container:UIComponent = new UIComponent();
    gr.addElementAt(container, 0);

    // Draw the full circle with colors
    circleToMask.graphics.beginGradientFill(GradientType.RADIAL, [0x000000, 0x000000], [0, 1], [80, 130]);
    circleToMask.graphics.drawCircle(0, 0, 50);
    circleToMask.graphics.endFill();

    // Add the circle
    container.addChildAt(circleToMask, 0);

    // Add the mask
    container.addChild(circleMask);

    Set the position of the circle
    circleToMask.x = (circleMask.x = 14);
    circleToMask.y = (circleMask.y = 14);
    circleToMask.mask = circleMask;

    // Draw the circle at 100%
    renderChart(1);
}
private function renderChart(percentage:Number):void
{
    circleMask.graphics.clear();
    circleMask.graphics.beginFill(0);

    // Draw the circle at the given percentage            /------ set the begin at the middle top
    drawPieMask(circleMask.graphics, percentage, 100, -1.57, 8);
    circleMask.graphics.endFill();
}

// Function from flassari (a little simplified)
private function drawPieMask(graphics:Graphics, percentage:Number, radius:Number = 50, rotation:Number = 0, sides:int = 6):void {
    radius /= Math.cos(1/sides * Math.PI);
    var lineToRadians:Function = function(rads:Number):void {
        graphics.lineTo(Math.cos(rads) * radius + x, Math.sin(rads) * radius + y);
    };
    var sidesToDraw:int = Math.floor(percentage * sides);
    for (var i:int = 0; i <= sidesToDraw; i++)
        lineToRadians((i / sides) * (Math.PI * 2) + rotation);
    if (percentage * sides != sidesToDraw)
        lineToRadians(percentage * (Math.PI * 2) + rotation);
}

そしてここでは、mxml:

<s:Group verticalCenter="0" horizontalCenter="0">
    <s:Rect width="100%" height="100%">
        <s:fill>
            <s:SolidColor color="0xcccccc"/>
        </s:fill>
    </s:Rect>
    <s:Label id="lab" verticalCenter="0" horizontalCenter="0" text="test"/>
    <s:Group id="gr" cacheAsBitmap="true" blendMode="layer" verticalCenter="0" horizontalCenter="0">
        <s:Group verticalCenter="0" horizontalCenter="0" blendMode="erase" cacheAsBitmap="true">
            <s:Ellipse width="30" height="30">
                <s:fill>
                    <s:SolidColor color="0"/>
                </s:fill>
            </s:Ellipse>
        </s:Group>
    </s:Group>
</s:Group>

助けてくれてありがとう

于 2013-10-03T09:24:55.693 に答える