2013-10-02 218 views
0

我正在嘗試做一個圓形的進度條,但我被卡住了。彎曲圓形進度條

我在繪製彩色圓圈時沒有任何問題,但我不知道如何去除中心的顏色以及如何去除代表缺失百分比的小部分。

實際的解決方案是在背景中使用圖像,我將其替換爲5%。它可以工作,但它很沉重,如果我需要改變圓的顏色,我必須重畫所有20張照片。

它有任何解決方案,讓我動態地繪製這個「進展圈」?

+0

的[畫圓弧中可能重複MXML圖形](http://stackoverflow.com/questions/5058051/draw-a-circular-arc-in-mxml-graphics) – RIAstar

回答

1

謝謝你們。

最後,我從我用從flassari代碼繪製和更新圈子http://flassari.is/2009/11/pie-mask-in-as3/

兩個Josh的代碼和腳本(編輯做在還原模式,從100%到0%),和喬希在圈子中心打洞的方式。

這裏是我使用的主要代碼:

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> 

感謝你們的幫助

+0

請確保您標記我的或您的答案正確以關閉此問題並保持系統清潔。很高興我能以某種方式提供幫助。 –

+0

是的,我只是等待1天來標記我自己的答案。謝謝。 – blaazzze

3

這比我想象的要複雜得多。

您需要使用alpha蒙版來在圓中打洞。這是一個很難想象的問題,因爲很少有關於如何正確完成它的文檔,但一旦找出來就比較容易。您需要創建一個Group,其中blendMode爲「圖層」,並將cacheAsBitmap設置爲true。然後,您使用Ellipse創建自己的形狀,並創建一個組(必須在以下),其中blendMode的「擦除」和cacheAsBitmap設置爲true。在該組中,您將繪製想要用於在父形狀中打孔的形狀。

例子:

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

即採取直接從一個應用程序我最近建立這樣我就可以驗證它的工作原理。這將創建一個直徑爲84px的圓,中心有一個64px的孔。

編輯:正如RIAStar在評論中指出的那樣,您實際上可以用中風而不是我複雜的方式做到這一點。

從他的評論:

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

要進行實際的進展,你需要做一點TRIG的。不幸的是,沒有辦法(我知道)沒有這樣做,而沒有貝塞爾路徑。因此,您基本上創建了一個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之間的數字。確保將其限制在該範圍內。如果我沒有記錯的話,如果它超出了這些範圍,就會中斷。

希望有幫助。再一次,我不能真正向你展示更多,但它應該足以讓你開始

+1

第一部分似乎對我來說過於複雜。爲什麼不使用一個簡單的橢圓來代替填充?像''應該具有相同的效果。 – RIAstar

+0

@RIAstar ......現在我覺得自己像個白癡。我很習慣用口罩打孔,我忘了你可以這樣做。好決定。 –