dbuzin
dbuzin

Reputation: 365

Jetpack Compose draw custom border

I need to make a box with border like this (on pic)

border example

Think i have to use drawWithContent method with clipRect, but can't find valid coordinates

Upvotes: 3

Views: 2018

Answers (1)

Atras VidA
Atras VidA

Reputation: 445

This is similar

enter image description here

@Preview
@Composable
fun QrBorder() {
    Box(modifier = Modifier.size(300.dp)) {
        Canvas(
            modifier = Modifier
                .matchParentSize()
                .padding(16.dp)
        ) {
            this.drawQrBorderCanvas(
                curve = 32.dp,
                strokeWidth = 3.dp,
                capSize = 62.dp,
                gapAngle = 30
            )
        }
    }
}

drawQrBorderCanvas



private fun DrawScope.drawQrBorderCanvas(
    borderColor: Color = Color.White,
    curve: Dp,
    strokeWidth: Dp,
    capSize: Dp,
    gapAngle: Int = 20,
    shadowSize: Dp = strokeWidth * 2,
    cap: StrokeCap = StrokeCap.Square,
    lineCap: StrokeCap = StrokeCap.Round,
) {

    val curvePx = curve.toPx()

    val mCapSize = capSize.toPx()

    val width = size.width
    val height = size.height

    val sweepAngle = 90 / 2 - gapAngle / 2f

    strokeWidth.toPx().toInt()
    for (i in 4..shadowSize.toPx().toInt() step 2) {
        drawRoundRect(
            color = Color(0x05000000),
            size = size,
            topLeft = Offset(0f, 0f),
            style = Stroke(width = i * 1f),
            cornerRadius = CornerRadius(
                x = curvePx,
                y = curvePx
            ),
        )
    }

    val mCurve = curvePx * 2

    drawArc(
        color = borderColor,
        style = Stroke(strokeWidth.toPx(), cap = cap),
        startAngle = 0f,
        sweepAngle = sweepAngle,
        useCenter = false,
        size = Size(mCurve , mCurve ),
        topLeft = Offset(
            width - mCurve , height - mCurve
        )
    )
    drawArc(
        color = borderColor,
        style = Stroke(strokeWidth.toPx(), cap = cap),
        startAngle = 90 - sweepAngle,
        sweepAngle = sweepAngle,
        useCenter = false,
        size = Size(mCurve , mCurve ),
        topLeft = Offset(
            width - mCurve , height - mCurve
        )
    )

    drawArc(
        color = borderColor,
        style = Stroke(strokeWidth.toPx(), cap = cap),
        startAngle = 90f,
        sweepAngle = sweepAngle,
        useCenter = false,
        size = Size(mCurve, mCurve),
        topLeft = Offset(
            0f, height - mCurve
        )
    )
    drawArc(
        color = borderColor,
        style = Stroke(strokeWidth.toPx(), cap = cap),
        startAngle = 180 - sweepAngle,
        sweepAngle = sweepAngle,
        useCenter = false,
        size = Size(mCurve , mCurve ),
        topLeft = Offset(
            0f, height - mCurve
        )
    )

    drawArc(
        color = borderColor,
        style = Stroke(strokeWidth.toPx(), cap = cap),
        startAngle = 180f,
        sweepAngle = sweepAngle,
        useCenter = false,
        size = Size(mCurve , mCurve ),
        topLeft = Offset(
            0f, 0f
        )
    )

    drawArc(
        color = borderColor,
        style = Stroke(strokeWidth.toPx(), cap = cap),
        startAngle = 270 - sweepAngle,
        sweepAngle = sweepAngle,
        useCenter = false,
        size = Size(mCurve , mCurve ),
        topLeft = Offset(
            0f, 0f
        )
    )


    drawArc(
        color = borderColor,
        style = Stroke(strokeWidth.toPx(), cap = cap),
        startAngle = 270f,
        sweepAngle = sweepAngle,
        useCenter = false,
        size = Size(mCurve, mCurve ),
        topLeft = Offset(
            width - mCurve , 0f
        )
    )

    drawArc(
        color = borderColor,
        style = Stroke(strokeWidth.toPx(), cap = cap),
        startAngle = 360 - sweepAngle,
        sweepAngle = sweepAngle,
        useCenter = false,
        size = Size(mCurve , mCurve ),
        topLeft = Offset(
            width - mCurve , 0f
        )
    )


    drawLine(
        SolidColor(borderColor), Offset(width, height - mCapSize), Offset(width, height - curvePx),
        strokeWidth.toPx(), lineCap,
    )

    drawLine(
        SolidColor(borderColor), Offset(width - mCapSize, height), Offset(width - curvePx, height),
        strokeWidth.toPx(), lineCap,
    )

    drawLine(
        SolidColor(borderColor), Offset(mCapSize, height), Offset(curvePx, height),
        strokeWidth.toPx(), lineCap,
    )

    drawLine(
        SolidColor(borderColor), Offset(0f, height - curvePx), Offset(0f, height - mCapSize),
        strokeWidth.toPx(), lineCap
    )

    drawLine(
        SolidColor(borderColor), Offset(0f, curvePx), Offset(0f, mCapSize),
        strokeWidth.toPx(), lineCap,
    )

    drawLine(
        SolidColor(borderColor), Offset(curvePx, 0f), Offset(mCapSize, 0f),
        strokeWidth.toPx(), lineCap,
    )

    drawLine(
        SolidColor(borderColor), Offset(width - curvePx, 0f), Offset(width - mCapSize, 0f),
        strokeWidth.toPx(), lineCap,
    )

    drawLine(
        SolidColor(borderColor), Offset(width, curvePx), Offset(width, mCapSize),
        strokeWidth.toPx(), lineCap
    )

}


Upvotes: 8

Related Questions