2015-09-21 158 views
6

我想繪製一個心形的帆布在Android中使用路徑。代碼如下:Android - 用部分顏色填充路徑

@Override 
    protected void onDraw(Canvas canvas) { 
     super.onDraw(canvas); 


     // Fill the canvas with background color 
     canvas.drawColor(Color.WHITE); 
     // paint.setShader(null); 

     // Defining of the heart path starts 
     path.moveTo(left + WIDTH/2, top + HEIGHT/4); // Starting point 
     // Create a cubic Bezier cubic left path 
     path.cubicTo(left+WIDTH/5,top, 
       left+WIDTH/4,top+4*HEIGHT/5, 
       left+WIDTH/2, top+HEIGHT); 
     // This is right Bezier cubic path 
     path.cubicTo(left + 3 * WIDTH/4, top + 4 * HEIGHT/5, 
       left + 4 * WIDTH/5, top, 
       left + WIDTH/2, top + HEIGHT/4); 

     paint.setShader(new LinearGradient(0, canvas.getHeight()/4, canvas.getWidth(), canvas.getHeight()/4, new int[]{Color.RED, Color.YELLOW, Color.GREEN}, new float[]{0, 0.6f, 1}, Shader.TileMode.CLAMP)); 

     canvas.drawPath(path, paint); 

     heart_outline_paint.setColor(getResources().getColor(R.color.heart_outline_color)); // Change the boundary color 
     heart_outline_paint.setStrokeWidth(4); 
     heart_outline_paint.setStyle(Paint.Style.STROKE); 
     canvas.drawPath(path, heart_outline_paint); 



    } 

我可以沒有任何問題提請心臟和我能夠填補用畫圖Fill選項心臟內部的顏色。但是,我應該能夠根據一些數據動態填充心臟,並且它無法一直充滿。什麼到目前爲止,我已經實現如下:

Heart Shape with Filled Color

我已經做了廣泛的搜尋和很多東西與此類似來到。其中一些包括:

  1. Android fill in part of a path?
  2. filling a circle gradually from bottom to top android

我也是在畫布轉換爲位圖和填充顏色使用Flood Fill Algorithm,它可以讓用戶填寫裏面的顏色的位圖內的念來過位圖。但是,我不希望位圖在接觸心臟內部時填充顏色,但要填充按鈕單擊操作。

我認爲filling a circle gradually from bottom to top android 會給予幫助我,但它使用了一個圈,我不精通的畫布,這使得我在適應圓代碼這樣的形狀非常薄弱。

如果有人對如何實現這一點有一些想法或見解,這將是非常有幫助的。乾杯。提前致謝。

P.S:我也嘗試了一些在Paint中使用setShader的技巧,但沒有什麼會給我想要的。

編輯:

我只是在繪製一個矩形在心臟與其他顏色相同的畫布背景的想法絆倒,這樣它看起來像它的填充一半!我仍在研究這個想法,並不確定這對我有多準確。如果有人有一個更好的主意,你是最受歡迎的。

enter image description here

+0

'「但是我應該能夠根據一些數據動態填充心臟,並且它不能一直充滿。」這意味着在實踐中? – pskink

+0

根據用戶獲得的積分,心臟需要填充10%或20%。 – San

回答

1

我使用了Canvas中的clipPath函數來實現我所需要的功能。我通過上述方法繪製心臟,並在其上繪製矩形,然後使用clipPath函數剪出心臟外部的區域。

 public static double filled_amount = .90; 
    path.moveTo(left_x_moveto, left_y_moveto); 
    path.cubicTo(left_x1, left_y1, left_x2, left_y2, left_x3, left_y3); 
    path.cubicTo(right_x2, right_y2, right_x1, right_y1, left_x_moveto, left_y_moveto); 
    path.close(); 
    Rect rect = new Rect((int)(canvas.getWidth()*.10),(int)(canvas.getHeight()*filled_amount),(int) canvas.getWidth(), (int) canvas.getHeight()); 
     canvas.clipPath(path); 
     paint.setColor(Color.WHITE); 
     paint.setStyle(Paint.Style.FILL); 
     canvas.drawPath(path, paint); 
     canvas.drawRect(rect, rect_paint); 
     heart_outline_paint.setColor(getResources().getColor(R.color.heart_outline_color)); // Change the boundary color 
     heart_outline_paint.setStrokeWidth(15); 
     heart_outline_paint.setStyle(Paint.Style.STROKE); 
     canvas.drawPath(path, heart_outline_paint); 

這會給我動態填充心臟所需的結果。動態更改filled_amount的值並調用invalidate()將使其看起來像心臟被動態填充。

@亨利的答案可能是更好的答案,但是這對我來說並沒有什麼竅門,我也沒有深入研究邊緣,所以在這裏和那裏都有一些曲折的東西。

1

你可以使用Bitmap Masking得到部分填充的心。你理想的做法是使用一個位圖掩蓋另一個。

在你的情況下,你可以在畫布上有一個填充的矩形,然後在新的位圖中有heart形狀作爲掩碼。然後,您可以通過更改背景矩形的高度來動態更改心臟的填充。

請參閱:https://stackoverflow.com/a/33483600/4747587。這包含部分填充Star的實施。這個想法是一樣的。

+0

謝謝你的回答,我已經通過在Canvas中使用Path和clipPath函數實現了。 – San

+0

是的。但'clipPath'不支持抗鋸齒。根據不同的形狀,您可能會看到之字形邊緣。如果你沒有太多細節,並且形狀是合適的,那麼'clipPath'就可以正常工作。 – Henry

+0

我沒有太多的細節,所以clipPath對我來說非常合適,謝謝你的寶貴建議。 – San