Following is my code for ticket like background.I used multiple sources on google to achieve this
class TicketShapeBackground(
private val circleRadius: Dp,
private val cornerSize: CornerSize
) : Shape {
override fun createOutline(size: Size, layoutDirection: LayoutDirection, density: Density): Outline {
return Outline.Generic(path = getPath(size, density))
}
private fun getPath(size: Size, density: Density): Path {
val roundedRect = RoundRect(size.toRect(), CornerRadius(cornerSize.toPx(size, density)))
val roundedRectPath = Path().apply { addRoundRect(roundedRect) }
return Path.combine(operation = PathOperation.Intersect, path1 = roundedRectPath, path2 = getTicketPath(size, density))
}
private fun getTicketPath(size: Size, density: Density): Path {
val middleX = size.width.div(other = 2)
val middleY = size.height.div(other = 2)
val circleRadiusInPx = with(density) { circleRadius.toPx() }
return Path().apply {
reset()
lineTo(x = 0F, y = 0F)
lineTo(middleX, y = 0F)
arcTo(
rect = Rect(
left = middleX.minus(circleRadiusInPx),
top = 0F.minus(circleRadiusInPx),
right = middleX.plus(circleRadiusInPx),
bottom = circleRadiusInPx
),
startAngleDegrees = 180F,
sweepAngleDegrees = -180F,
forceMoveTo = false
)
// Draw line to top right
lineTo(x = size.width, y = 0F)
lineTo(x = size.width, y = middleY)
// lineTo(x = size.width, y = 0F)
// lineTo(x = size.width, y = middleY)
arcTo(
rect = Rect(
left = size.width - circleRadiusInPx,
top = middleY - circleRadiusInPx,
right = size.width + circleRadiusInPx,
bottom = middleY + circleRadiusInPx
),
startAngleDegrees = 270f,
sweepAngleDegrees = -180F,
forceMoveTo = false
)
lineTo(x = size.width, y = size.height)
lineTo(middleX, y = size.height)
lineTo(x = 0F, y = size.height)
lineTo(x = size.width, y = size.height)
lineTo(0F, size.height)
lineTo(x = 0F, y = size.height)
arcTo(
rect = Rect(
left = 0F - circleRadiusInPx,
top = middleY - circleRadiusInPx,
right = circleRadiusInPx,
bottom = middleY + circleRadiusInPx
),
startAngleDegrees = 90f,
sweepAngleDegrees = -180F,
forceMoveTo = false
)
lineTo(x = 0F, y = 0F)
}
}
}
and use it like
Box(
Modifier.clip(TicketShapeBackground(34.dp, CornerSize(5.dp)))
.fillMaxSize()
.background(Color.Red)
) { }
Now the arc at the top ie after lineTo(middleX, y = 0F) I need to place an image inside the arc,like a circle image. How to achieve it. One way could be using a Box maybe but not sure how to do it, also I am not sure if it is a clean solution. Any help is appreciated .Thanks
Is this what you need?