I want to draw text below circle in canvas. Following is my code but text is drawn above circle.
canvas.drawCircle(getWidth() / 2, getHeight() / 2, radius, paint);
canvas.drawText(text, 0, (radius*2), textPaint);
Looking at it properly you need to set the y value based on height of the canvas, same way you did the circle, then adjust it to be Below based on radius.
canvas.drawCircle(getWidth() / 2, getHeight() / 2, radius, paint);
canvas.drawText(text, 0, (getHeight() / 2) + radius, textPaint);
One thing that may be confusing you is that the origion is the top left. And that increase in Y is downwards
You may need to add a few extra pixels based on text height. so (getHeight() / 2) + radius + 20
Related
I'm trying to use the PorterDuff library to trim a canvas circle and rectangle to form a quarter of a square in my custom view for my app, I managed to get it to work but not fully because it trims the square out but keeps the rest of the circle in, I'm using the SRC_IN mode which seems like the right mode to use from looking at the android documentation for it but it's not working as expected, this is a snippet of the onDraw method in my custom view class:
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int height = getHeight();
int width = getWidth();
canvas.drawCircle(width / 2, height / 2, (width + height) / 10, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
Rect rectangle = new Rect(0, 0, width / 2, height / 2);
paint.setColor(Color.RED);
canvas.drawRect(rectangle, paint);
}
I'm drawing the circle in the center of the screen and then drawing the square in the top left of the screen and the PorterDuff mode should basically get the intersected part between the shapes but it just trims non-intersected square part out but doesn't do the same for the circle.
This is what it looks like:
I can't tell what i'm doing wrong here, hopefully someone can point it out.
the issue is with the source, the rectangle is the source in this context, draw the rectangle first then use PorterDuff.Mode.SRC_IN to cut the circle based on it.
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int height = getHeight();
int width = getWidth();
Rect rectangle = new Rect(0, 0, width / 2, height / 2);
paint.setColor(Color.RED);
canvas.drawRect(rectangle, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawCircle(width / 2, height / 2, (width + height) / 10, paint);
}
I would like to draw something like this:
So on each photo I would like to put a circular sector (cut arc) with black area. How can I achieve that with using e.g.
canvas.draw(Path path, Paint paint);
I tried below but it didn t work out as I would like to:
Path path = new Path();
path.setFillType(Path.FillType.EVEN_ODD);
path.addCircle(getWidth() / 2, getHeight() / 2, getHeight() / 2, Path.Direction.CW);
path.addRect(0, getHeight() - 70, getWidth(), getHeight(), Path.Direction.CW);
You almost had it working. You just need to clip the canvas before drawing and use Path.FillType.INVERSE_EVEN_ODD to draw your sector:
// Limit the drawable region of the canvas (saving the state before)
canvas.save();
canvas.clipRect(new Rect(0, canvas.getHeight() - 70, canvas.getWidth(), canvas.getHeight()));
Path path = new Path();
path.setFillType(Path.FillType.INVERSE_EVEN_ODD);
path.addCircle(canvas.getWidth() / 2, canvas.getHeight() / 2, canvas.getHeight() / 2, Path.Direction.CW);
path.addRect(0, canvas.getHeight() - 70, canvas.getWidth(), canvas.getHeight(), Path.Direction.CW);
canvas.drawPath(path, paint);
// Restore the canvas to the saved state to remove clip
canvas.restore();
// Draw more things on the canvas...
Alternativelly, you can use Canvas.drawArc (documentation)
I assume from you question that you need to assign a fix height for your sector, so you will need to compute startAngle and sweepAngle (parameters of the drawArc method) based on that height (assuming a square image). Here is the sample code (API level 15 compatible):
int sectorHeigh = 70; // The height of your sector in pixels
// Compute the start angle based on your desired sector height
float startAngle = (float) Math.toDegrees(Math.asin((canvas.getHeight() / 2f - sectorHeigh) / (canvas.getHeight() / 2f)));
// Add the arc (calculating the sweepAngle based on startAngle)
canvas.drawArc(new RectF(0, 0, canvas.getWidth(), canvas.getHeight()), startAngle, 2 * (90 - startAngle), false, paint);
Another way to draw your sector using arcs is creating a Path object, add an arc using Path.addArc (documentation) and then use Canvas.drawPath (documentation) to draw it.
I'm looking at making something that looks like the following:
Which is basically a rectangle shape on the top left thats been rotated, and then two underneath it, tiled like it is.
I've had a go at doing it but just can't get it done, basically I use:
int x = getWidth();
int y = getHeight();
canvas.save();
canvas.rotate(-45);
canvas.drawRect(x/2, y/2, x/2+100, y/2+40, paint);
canvas.restore();
And I've noticed that what should be a rectangle rotated near the centre of the screen is instead one that is to the top right of the screen. When I try doing something similar to (0,0, 100,100) I don't get any rectangle at all.
I guess I'm confused whether the coordinate system changes when the rotation of the canvas is done, and what would be the easiest way in looking into getting the image above on android (besides just creating it in photoshop and adding the png).
The single argument rotate(angle) will use 0,0 as the pivot point.
If you want to rotate about your object, you should calculate some point on it to rotate about and use the 3 argument rotate(angle, pivotX, pivotY), ie:
int x = getWidth();
int y = getHeight();
canvas.save();
canvas.rotate(-45, x / 2, y / 2);
canvas.drawRect(x / 2, y / 2, x / 2 + 100, y / 2 + 40, paint);
canvas.restore();
I made your design just for fun:
int x = getWidth();
canvas.rotate(-45);
canvas.drawRect(-x, 0, x, h, green);
canvas.drawRect(-x, h, 0, 2 * h, purple);
canvas.drawRect(0, h, x, 2 * h, blue);
Where h is the height of the rectangle.
I will draw 4 squares in a canvas from 16px of distance of the screen corners.
I´m trying with this code:
canvas.drawRect(getWidth() - 91,getHeight() - 91, 75, 75, paint);
With this code, the square never appears.
How can i draw the 4 squares?
Here is some code I did pretty fast that ought to help you out & you should be able to optimize
int squareSize = 30;
int offset = 16;
// top left
canvas.drawRect(offset, offset, offset+squareSize, offset+squareSize, paint);
// top right
canvas.drawRect(getWidth() - offset - squareSize, offset, getWidth() - offset , offset+squareSize, paint);
// bottom left
canvas.drawRect(offset, getHeight() - offset - squareSize, offset+squareSize, getHeight() - offset, paint);
// bottom right
canvas.drawRect(getWidth() - offset - squareSize, getHeight() - offset - squareSize, getWidth() - offset , getHeight() - offset, paint);
Should be getWidth() - 75, getHeight() - 75.
Notice in the javadoc you have to give top left, bottom, right.http://developer.android.com/reference/android/graphics/Canvas.html#drawRect(float, float, float, float, android.graphics.Paint)
I am learning Android and trying to draw different shapes on the Canvas. At the moment I am stuck with an oval with different angles:
I've tried to use path.addRoundRect() method (the one which takes array of radiuses), but couldn't figure out what values should I pass there in order to achieve such shape. I've also tried using path.lineTo(), but could not achieve such result (it was kind of similar, but still not what I needed). What would be a good solution to accomplish this?
Edit 1 :What I have tried is following:
Path path= new Path();
path.moveTo(x - radius, y - radius/ 1.5f);
path.lineTo(x - radius/ 4, y - radius);
path.lineTo(x, y - radius);
path.lineTo(x + radius/ 2, y - radius);
path.lineTo(x + radius, y - radius/ 2);
path.lineTo(x, y + radius/ 2);
path.lineTo(x - radius/ 2, y + radius/ 1.5f);
path.lineTo(x - radius, y + radius/ 4);
path.lineTo(x - radius, y - radius/ 1.5f);
path.close();
Paint pathPaint = new Paint();
pathPaint.setColor(Color.BLACK);
pathPaint.setStrokeWidth(2.5f);
pathPaint.setDither(true);
pathPaint.setStyle(Style.STROKE);
pathPaint.setStrokeJoin(Join.ROUND);
pathPaint.setStrokeCap(Cap.ROUND);
pathPaint.setPathEffect(new CornerPathEffect(20));
pathPaint.setAntiAlias(true);
canvas.drawOval(new RectF(x - radius, y - radius+ 2, x + radius-2, y + radius- 2), pathPaint);
canvas.drawPath(path, pathPaint);
X and Y are some coordinates on a display and radius is a radius of the circle (I started drawing with a circle). Its equal to 14 px.
I've also tried this way:
float[] radii = new float[] {
5,
5,
1,
1,
5,
1,
1,
1,
};
path.addRoundRect(new RectF(x - radius, y - radius, x + radius,
y + radius),
radii, Direction.CW);
canvas.drawPath(path, pathPaint);
Try the Canvas.skew() function. There is a good example at the URL below. Skew "tilts" the points being drawn. You'll get different results based on the current center of the canvas, so translate() as needed to get the results you want.
http://css3files.com/transform/