I’m trying to make so that my content (Surface()
with Text()
) is clipped by circle and only what’s inside the circle is visible. I’m using BlendMode.DstIn
, but it doesn’t seem to work properly.
-
If I use solid black color, then I get the result as if the mask has not been applied at all.
-
If I use semi-transparent color, then I get the result of content within circle being semi-transparent as well, but everything outside stays.
@Composable
fun BlendModeTest() {
Box(
modifier = Modifier
.circularReveal(radius = 80.dp),
) {
Surface(
modifier = Modifier
.fillMaxWidth()
.height(300.dp),
color = Color.Gray,
) {
Text(
modifier = Modifier
.fillMaxSize()
.wrapContentSize(align = Alignment.Center),
text = "My content text",
)
}
}
}
@Stable
private fun Modifier.circularReveal(
radius: Dp,
): Modifier =
this
.graphicsLayer(
compositingStrategy = CompositingStrategy.Offscreen,
)
.drawWithContent {
drawContent()
drawCircle(
color = Color.Black,
radius = radius.toPx(),
blendMode = BlendMode.DstIn,
)
}
@Preview
@Composable
private fun Preview() {
MaterialTheme {
BlendModeTest()
}
}
Result with clipping circle of opaque Color.Black
Result with clipping circle of semi-transparent Color.Black.copy(alpha = 0.5f)
Why is the content outside of clipping circle ignored?
Documentation of BlendMode.DstIn
says it should not be drawn.