【问题标题】:How to draw rounded corner polygons in Jetpack Compose Canvas?如何在 Jetpack Compose Canvas 中绘制圆角多边形?
【发布时间】:2021-12-13 08:30:42
【问题描述】:

我正在尝试在 Jetpack Compose 中使用 Canvas 创建一个圆角三角形。

我尝试使用此代码绘制三角形:

@Composable
fun RoundedTriangle() {
    Canvas(modifier = Modifier.size(500.dp)) {
        val trianglePath = Path().apply {
            val height = size.height
            val width = size.width
            moveTo(width / 2.0f, 0f)
            lineTo(width, height)
            lineTo(0f, height)
        }
            drawPath(trianglePath, color = Color.Blue)
    }
}

但我不知道如何圆角。我也尝试使用arcTo,但无法得到合适的结果。

我怎样才能画出像下图这样的东西?

【问题讨论】:

    标签: android kotlin canvas android-jetpack-compose rounded-corners


    【解决方案1】:

    对于Stroke,您可以像这样指定舍入:

    drawPath(
        ...
        style = Stroke(
            width = 2.dp.toPx(),
            pathEffect = PathEffect.cornerPathEffect(4.dp.toPx())
        )
    )
    

    然而Fill 似乎缺乏支持四舍五入。我创建了一个feature request,请加注星标。

    但是 Canvas 有drawOutline 函数,它接受Outline,可以包装Path,和Paint,你可以指定pathEffect

    Canvas(modifier = Modifier.fillMaxWidth().aspectRatio(1f)) {
        val rect = Rect(Offset.Zero, size)
        val trianglePath = Path().apply {
            moveTo(rect.topCenter)
            lineTo(rect.bottomRight)
            lineTo(rect.bottomLeft)
            close()
        }
    
        drawIntoCanvas { canvas ->
            canvas.drawOutline(
                outline = Outline.Generic(trianglePath),
                paint = Paint().apply {
                    color = Color.Black
                    pathEffect = PathEffect.cornerPathEffect(rect.maxDimension / 3)
                }
            )
        }
    }
    

    Path助手:

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

    结果:

    【讨论】:

    • 你知道如何将其应用于正方形吗?
    • @AouledIssa 只需在路径上再添加一个点,例如this
    • 感谢您的回答!然而,这将呈现一个旋转 45° 的正方形,因为您要锚定边缘中心。我可以使用边缘实现正确的结果,但也可以关闭路径。
    • @AouledIssa 如果您需要一个普通的正方形,而不是旋转,您只需使用DrawScope.drawRoundRect
    • true 但这不会给你super circle 或平滑圆边的效果。
    【解决方案2】:

    根据@philip-dukhov 的回答,如果有人有兴趣将其应用于正方形

    @Composable
    fun SquirclePath(
        modifier: Modifier,
        smoothingFactor: Int = 60,
        color: Color,
        strokeWidth: Float,
    ) {
        Canvas(
            modifier = modifier
        ) {
            val rect = Rect(Offset.Zero, size)
            val percent = smoothingFactor.percentOf(rect.minDimension)
            val squirclePath = Path().apply {
                with(rect) {
                    lineTo(topRight)
                    lineTo(bottomRight)
                    lineTo(bottomLeft)
                    lineTo(topLeft)
                    // this is where the path is finally linked together
                    close()
                }
            }
    
            drawIntoCanvas { canvas ->
                canvas.drawOutline(
                    outline = Outline.Generic(squirclePath),
                    paint = Paint().apply {
                        this.color = color
                        this.style = PaintingStyle.Fill
                        this.strokeWidth = strokeWidth
                        pathEffect = PathEffect.cornerPathEffect(percent)
                    }
                )
            }
        }
    }
    
    fun Int.percentOf(target:Float) = (this.toFloat() / 100) * target
    

    【讨论】:

    • @philip-dukhov 我无法将整个代码放入评论中,所以我将其发布在这里。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-18
    • 2015-01-08
    • 1970-01-01
    • 2011-12-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多