How to draw a triangle, a star, a square or a heart on the canvas?
For future direct answer seekers, I have drawn an almost symmetric star using canvas, as shown in the image:
The main tool is using Paths.
Assuming you have setup:
Paint paint = new Paint();paint.setColor(Color.WHITE);paint.setAntiAlias(true);paint.setStyle(Paint.Style.STROKE);Path path = new Path();
Then in you onDraw you can use the path like I do below. It will scale properly to any sizes canvas
@Overrideprotected void onDraw(Canvas canvas) { float mid = getWidth() / 2; float min = Math.min(getWidth(), getHeight()); float fat = min / 17; float half = min / 2; float rad = half - fat; mid = mid - half; paint.setStrokeWidth(fat); paint.setStyle(Paint.Style.STROKE); canvas.drawCircle(mid + half, half, rad, paint); path.reset(); paint.setStyle(Paint.Style.FILL); // top left path.moveTo(mid + half * 0.5f, half * 0.84f); // top right path.lineTo(mid + half * 1.5f, half * 0.84f); // bottom left path.lineTo(mid + half * 0.68f, half * 1.45f); // top tip path.lineTo(mid + half * 1.0f, half * 0.5f); // bottom right path.lineTo(mid + half * 1.32f, half * 1.45f); // top left path.lineTo(mid + half * 0.5f, half * 0.84f); path.close(); canvas.drawPath(path, paint); super.onDraw(canvas);}
For everybody that needs a heart shape:
import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Paint.Style; import android.graphics.Path; import android.view.View; public class Heart extends View { private Path path; private Paint paint; public Heart(Context context) { super(context); path = new Path(); paint = new Paint(Paint.ANTI_ALIAS_FLAG); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); // Fill the canvas with background color canvas.drawColor(Color.WHITE); paint.setShader(null); float width = getContext().getResources().getDimension(R.dimen.heart_width); float height = getContext().getResources().getDimension(R.dimen.heart_height); // Starting point path.moveTo(width / 2, height / 5); // Upper left path path.cubicTo(5 * width / 14, 0, 0, height / 15, width / 28, 2 * height / 5); // Lower left path path.cubicTo(width / 14, 2 * height / 3, 3 * width / 7, 5 * height / 6, width / 2, height); // Lower right path path.cubicTo(4 * width / 7, 5 * height / 6, 13 * width / 14, 2 * height / 3, 27 * width / 28, 2 * height / 5); // Upper right path path.cubicTo(width, height / 15, 9 * width / 14, 0, width / 2, height / 5); paint.setColor(Color.RED); paint.setStyle(Style.FILL); canvas.drawPath(path, paint); } }
Sorry for all the numbers but these worked best for me :) The result looks like this:
You have to find out the math behind that figures. The triangle and the star are quite easy to draw. Here is how you can draw a heart: http://www.mathematische-basteleien.de/heart.htm
To draw special paths you should create them by adding points, ellipses etc. The canvas supports a clipping mask of a specified path, so you can set the clipping mask of a heart, push the paths to the matrix, draw the content of the heart, and then pop it again.
That's what I'm doing to achieve a simulated 2D page curl effect on andriod: http://code.google.com/p/android-page-curl/
Hope this helps!