I'm drawing a globe by rendering Paths. The edge of the globe is very sharp and I'd like to soften the edge to make it more visually appealing.
For performance, I'm not doing hidden line removal. I'm just calculating whether each point on the Path is visible (the side of the globe the user is viewing) and drawing the Path out to the nearest corner. To hide this, I draw a Bitmap over the entire view then punch a hole through to see the globe.
To soften the edge, I'm trying to create a ring with a radial gradient transparency. This method creates the mask:
private void createMask(int width, int height, double radius) {
if(radius==0){return;}
if (mask != null) {
mask.recycle();
}
mask = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_4444);
// create a RadialGradient
RadialGradient gradient = new android.graphics.RadialGradient(
kHorizontalOffset, kVerticalOffset,
30f, 0x00FF0000, 0xFFFF0000,
android.graphics.Shader.TileMode.CLAMP);
// TODO move to init()
Paint p = new Paint();
p.setShader(gradient);
//p.setColor(0xFF000000);
p.setColor(0xFFFF0000);
p.setStrokeWidth(20f);
p.setStrokeCap(Paint.Cap.ROUND);
p.setStyle(Paint.Style.STROKE);
p.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OVER));
Canvas maskCanvas = new Canvas(mask);
maskCanvas.drawColor(Color.BLACK);
final RectF rect = new RectF();
rect.set((float)(kHorizontalOffset - radius + 50), (float)(kVerticalOffset - radius + 50),
(float)(kHorizontalOffset + radius - 50), (float)(kVerticalOffset + radius - 50));
// draw transparent circle using the maskPaint
maskCanvas.drawCircle(kHorizontalOffset, this.getHeight() - kVerticalOffset, (float) radius, maskPaint);
// draw the radial gradient ring
maskCanvas.drawArc(rect, -90, 360, false, p);
}
My problem is that no matter what PortDuff.Mode I use, I always get a solid ring (or no ring) as in this example, where the ring is offset from the edge and coloured red so that I can see what's going on.
Any ideas on how to make this work?