当 2 行与 Canvas 重叠时如何保持相同的颜色 alpha

Posted

技术标签:

【中文标题】当 2 行与 Canvas 重叠时如何保持相同的颜色 alpha【英文标题】:How to keep the same color alpha when 2 lines are being overlapped with Canvas 【发布时间】:2021-09-14 10:12:08 【问题描述】:

我正在使用 CanvasdrawLines(...) 方法,我有 2 条线相互交叉/重叠,这些线的颜色 alpha 为 0.3f。

问题在于,当相互交叉时,此 alpha 会累积,将它们的交叉点转换为 0.6f 的颜色 alpha

有没有什么办法可以保持原来的alpha,即使它们相互交叉?

【问题讨论】:

你如何“画”出这两条线? DrawScope里面我使用drawLine(...)函数 【参考方案1】:

步骤1.从起点、终点和笔划宽度创建Path

fun linePath(start: Offset, end: Offset, strokeWidth: Float) =
    Path().apply 
        // calculations from https://***.com/a/7854359/3585796
        val size = end - start
        val perpendicular = Offset(size.y, -size.x)
        val length = hypot(size.x, size.y)
        val normalized = Offset(perpendicular.x / length, perpendicular.y / length)
        val points = listOf(
            end + normalized * strokeWidth / 2f,
            start + normalized * strokeWidth / 2f,
            start - normalized * strokeWidth / 2f,
            end - normalized * strokeWidth / 2f,
        )
        moveTo(points.last())
        points.forEach(::lineTo)
    

fun Path.moveTo(offset: Offset) =
    moveTo(offset.x, offset.y)

fun Path.lineTo(offset: Offset) =
    lineTo(offset.x, offset.y)

第 2 步。使用clipPath 绘制所需的线条部分:

Canvas(Modifier.fillMaxSize()) 
    val rect = Rect(Offset.Zero, size)
    val firstLinePath = linePath(
        start = rect.topLeft,
        end = rect.bottomRight,
        strokeWidth = 20f,
    )
    val firstLineColor = Color.Red
    val secondLinePath = linePath(
        start = rect.topRight,
        end = rect.bottomLeft,
        strokeWidth = 20f,
    )
    val secondLineColor = Color.Green
    val sharedAlpha = 0.5f

    // draw first line without intersection part 
    clipPath(secondLinePath, clipOp = ClipOp.Difference) 
        drawPath(firstLinePath, color = firstLineColor.copy(sharedAlpha))
    
    // draw second line without intersection part
    clipPath(firstLinePath, clipOp = ClipOp.Difference) 
        drawPath(secondLinePath, color = secondLineColor.copy(sharedAlpha))
    
    // draw intersection part with mixed color
    clipPath(secondLinePath) 
        val blendedColor = Color(
            ColorUtils.blendARGB(
                firstLineColor.toArgb(),
                secondLineColor.toArgb(),
                0.5f
            )
        )

        drawPath(firstLinePath, color = blendedColor.copy(sharedAlpha))
    

结果:

【讨论】:

【参考方案2】:

没有。这是不可能的,因为我们必须修改 Composable 的特定“部分”的 alpha 值,这不是一件容易实现的事情。你需要改变你的方法。

【讨论】:

很伤心,但我会看看我能做些什么

以上是关于当 2 行与 Canvas 重叠时如何保持相同的颜色 alpha的主要内容,如果未能解决你的问题,请参考以下文章

相同的声音重叠使其非常响亮。提示与技巧?

响应式视图中表格中的重叠行

在将python turtle canvas转换为位图时如何保持画布大小

如何捕捉鼠标点击事件到重叠的ItemsControl

Amazon Redshift:当找到的表 id 不匹配时,如何将 `stl_load_errors` 行与正确的表名相关联?

Android Canvas设置绘画时重叠部分的处理模式含效果图