For example if in an onboarding flow you wanted to darken the rest of the screen and then draw a light circle around some part of the screen to highlight something like a spotlight how would you do it? The circle needs to have gradient edges. It also needs to at least be compatible with jetpack compose.
This is my attempt.
// Background content, in my real use case this would be something else
Image(
modifier = Modifier.matchParentSize(),
painter = painterResource(id = R.drawable.hqdefault), contentDescription = "")
val overlayShadeColor = Color.Black.copy(alpha = 0.8f)
val gradient = Brush.radialGradient(
.2f to Color.Transparent,
.5f to overlayShadeColor)
val radius = 120.dp
Canvas(modifier = Modifier.fillMaxSize().graphicsLayer {
alpha = .99f
}) {
// Dark overlay
drawRect(overlayShadeColor)
// Circle to punch through the overlay
drawCircle(
color = Color.White,
radius = radius.toPx(),
blendMode = BlendMode.Clear
)
// Circle that adds back a gradient edge
drawCircle(
gradient,
radius = radius.toPx(),
)
}
The flaw with my attempt is that it leaves a very small (probably 1 hardware pixel wide) line on the edge where the circles meet with the background. Maybe canvas is not the right approach and there is an easier way to do this. I am open to suggestions.
The punch hole is a bit overkill. SRC Blend will work the same
drawRect(overlayShadeColor)
drawCircle(
gradient,
radius = radius.toPx(),
blendMode = BlendMode.Src
)