2015-09-21 16 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:また、ペイントでsetShaderを使用していくつかのトリックを試してみましたが、何も私に欲しいものはありません。

EDIT:その半分が満たされたように見えますように、私はちょうどキャンバスの背景と同じ色で、別の心の上に四角形を描画するという考えにつまずい

!!私はまだアイデアに取り組んでおり、これがどれほど正確であるかはわかりません。誰かがより良い考えを持っているなら、あなたは大歓迎です。

enter image description here

+0

「しかし、私はいくつかのデータに基づいて心臓を動的に満たすことができなければならず、常に完全に満たすことはできません。 – pskink

+0

心臓のように、ユーザーが獲得したポイントに応じて10%または20%を充填する必要があります。 – San

答えて

1

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を使用することができます。あなたが理想的にここでやることは、もう一方をマスクするために1つのビットマップを使用することです。

あなたのケースでは、キャンバスに塗りつぶした矩形があり、マスクとして機能する新しいビットマップにheartシェイプがあります。その後、背景の長方形の高さを変更することによって、心臓の充填を動的に変更することができます。

これを参照してください:https://stackoverflow.com/a/33483600/4747587。これには、部分を部分的に埋め込むの実装が含まれています。アイデアは同じです。

+0

お返事ありがとうございました。私はCanvasのPathとclipPath関数を使用して実現しました。 – San

+0

はい。しかし、 'clipPath'はアンチエイリアスをサポートしていません。さまざまな形状に基づいて、ジグザグのエッジが表示されることがあります。あまり細かいことがなく、形状が適切なものであれば、 'clipPath'はうまく動作します。 – Henry

+0

私はclipPathが私のために完全に機能するので、あなたの貴重な提案に感謝します。 – San