我正在尝试将混合模式应用于 Jetpack compose Canvas 中的两个形状。基于this blog尽管我没有得到类似的结果,但我大致知道预期的输出应该是什么样子。
例如,使用以下具有两个形状的简单 Box + Canvas,使用混合模式 SrcIn
Box(
contentAlignment = Alignment.Center,
modifier = Modifier.size(290.dp)
) {
val sizeInPx = with(LocalDensity.current) { 150.dp.toPx() }
Canvas(
modifier = Modifier.fillMaxSize()
) {
drawCircle(
color = Color.Red,
radius = sizeInPx,
)
drawRect(
color = Color.Blue,
size = Size(sizeInPx, sizeInPx),
blendMode = BlendMode.SrcIn
)
}
}
我期望有一个红色圆圈,以及一个剪裁成红色圆圈形状的蓝色正方形。然而输出 UI 就像 no blend mode has been added at all
我做错了什么?
最佳答案
将 alpha 更改为小于 1f 会创建一个图层作为缓冲区,这就是它起作用的原因。如果您不想更改 alpha,实现此目的的其他方法是直接使用图层。你可以看我的回答here
Canvas(modifier = canvasModifier) {
val canvasWidth = size.width.roundToInt()
val canvasHeight = size.height.roundToInt()
with(drawContext.canvas.nativeCanvas) {
val checkPoint = saveLayer(null, null)
drawCircle(
color = Color.Red,
radius = sizeInPx,
)
drawRect(
color = Color.Blue,
size = Size(sizeInPx, sizeInPx),
blendMode = BlendMode.SrcIn
)
restoreToCount(checkPoint)
}
}
在 Painter 代码中,Android 团队将其用作
private fun configureAlpha(alpha: Float) {
if (this.alpha != alpha) {
val consumed = applyAlpha(alpha)
if (!consumed) {
if (alpha == DefaultAlpha) {
// Only update the paint parameter if we had it allocated before
layerPaint?.alpha = alpha
useLayer = false
} else {
obtainPaint().alpha = alpha
useLayer = true
}
}
this.alpha = alpha
}
}
并检查 Alpha 以应用图层
fun DrawScope.draw(
size: Size,
alpha: Float = DefaultAlpha,
colorFilter: ColorFilter? = null
) {
configureAlpha(alpha)
configureColorFilter(colorFilter)
configureLayoutDirection(layoutDirection)
// b/156512437 to expose saveLayer on DrawScope
inset(
left = 0.0f,
top = 0.0f,
right = this.size.width - size.width,
bottom = this.size.height - size.height
) {
if (alpha > 0.0f && size.width > 0 && size.height > 0) {
if (useLayer) {
val layerRect = Rect(Offset.Zero, Size(size.width, size.height))
// TODO (b/154550724) njawad replace with RenderNode/Layer API usage
drawIntoCanvas { canvas ->
canvas.withSaveLayer(layerRect, obtainPaint()) {
onDraw()
}
}
} else {
onDraw()
}
}
}
}
}
关于android - Jetpack compose Canvas 混合模式未按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73313025/