2015-09-21 17 views
6

Sto provando a disegnare una tela a forma di cuore utilizzando il percorso in Android. Il codice è il seguente:Android - Riempi percorso con colore in parte

@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); 



    } 

io sono in grado di trarre cuore senza alcun problema e io sono in grado di riempire di colore all'interno del cuore utilizzando l'opzione Fill in Paint. Ma dovrei essere in grado di riempire il cuore in modo dinamico secondo alcuni dati e non può essere riempito completamente tutto il tempo. Quello che ho ottenuto finora è il seguente:

Heart Shape with Filled Color

ho fatto una lunga ricerca e sono imbattuto in un sacco di cose simili a questo. Alcuni dei quali comprende:

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

Ho anche imbattuto il concetto di conversione della tela per bitmap e riempire di colore all'interno della bitmap utilizzando Flood Fill Algorithm che permette agli utenti di compilare i colori all'interno della bitmap. Tuttavia, non voglio che la bitmap riempia il colore mentre si tocca il cuore ma si riempia mentre si fa clic con un pulsante.

Ho pensato che filling a circle gradually from bottom to top android mi avrebbe aiutato ma utilizza un cerchio e non sono molto esperto in Canvas, il che mi rende molto debole nell'adattare il codice del cerchio a una tale forma.

Se qualcuno ha qualche idea o qualche idea su come ottenere ciò, sarà davvero d'aiuto. Saluti. Grazie in anticipo.

P.S: Ho anche provato alcuni trucchi utilizzando setShader in Paint ma nulla mi darebbe quello che voglio.

EDIT:

Ho appena incappato in un idea di disegnare un rettangolo sopra il cuore con un altro colore stesso come sfondo della tela in modo che avrà un aspetto come il suo mezzo pieno !! Sto ancora lavorando all'idea e non sono sicuro di quanto sia preciso per me. Se qualcuno ha un'idea migliore, sei il benvenuto.

enter image description here

+0

'" Ma dovrei essere in grado di riempire il cuore in modo dinamico secondo alcuni dati e non può essere riempito completamente tutto il tempo. "Che significa in pratica? – pskink

+0

Come il cuore deve essere riempito del 10% o del 20% a seconda dei punti acquisiti dall'utente. – San

risposta

1

Ho utilizzato la funzione clipPath disponibile in Canvas per ottenere ciò di cui avevo bisogno. Disegna il cuore sopra il metodo e disegno un rettangolo sopra di esso, e io uso la funzione clipPath per ritagliare la regione che è fuori dal cuore.

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

Questo mi darà il risultato desiderato di riempire il cuore in modo dinamico. Cambiando il valore di filled_amount in modo dinamico e chiamando invalidate(), sembrerà che il cuore venga riempito dinamicamente.

@ La risposta di Henry potrebbe essere migliore, ma questo ha fatto il trucco per me e io non guardo profondamente verso i bordi così un po 'di zig-zag qua e là va bene.

1

Si potrebbe utilizzare Bitmap Masking per ottenere un cuore parzialmente riempito. Quello che idealmente fai qui è usare una bitmap per mascherare l'altra.

Nel tuo caso potresti avere un rettangolo pieno nell'area di disegno e hai quindi la forma heart in una nuova bitmap per fungere da maschera. È quindi possibile modificare dinamicamente il riempimento del cuore modificando l'altezza del rettangolo di sfondo.

Riferimento: https://stackoverflow.com/a/33483600/4747587. Questo contiene l'implementazione di che riempie parzialmente una stella. L'idea è la stessa.

+0

Grazie per la tua risposta, l'ho ottenuta utilizzando Path in Canvas e la funzione clipPath. – San

+0

Sì. Ma 'clipPath' non supporta l'anti-aliasing. Sulla base di forme diverse, potresti iniziare a vedere i bordi a zig-zag. Se non si hanno troppi dettagli e se la forma è adatta, 'clipPath' funzionerebbe correttamente. – Henry

+0

Non ho molti dettagli, quindi clipPath funziona perfettamente per me, grazie per il tuo prezioso suggerimento. – San

Problemi correlati