Skip to content

Instantly share code, notes, and snippets.

@dkaera
Last active April 29, 2023 12:23
Show Gist options
  • Save dkaera/0feffe059ac80fc68aa5a7d26fa6c6a3 to your computer and use it in GitHub Desktop.
Save dkaera/0feffe059ac80fc68aa5a7d26fa6c6a3 to your computer and use it in GitHub Desktop.
Jetpack compose TicketShape with specified corners.
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.material.Surface
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.composed
import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.*
import androidx.compose.ui.graphics.drawscope.Stroke
import androidx.compose.ui.graphics.drawscope.scale
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
class TicketShape(
private val cornerTopStart: Dp = 0.dp,
private val cornerTopEnd: Dp = 0.dp,
private val cornerBottomStart: Dp = 0.dp,
private val cornerBottomEnd: Dp = 0.dp,
) : Shape {
constructor(cornerRadius: Dp) : this(
cornerTopStart = cornerRadius,
cornerTopEnd = cornerRadius,
cornerBottomEnd = cornerRadius,
cornerBottomStart = cornerRadius,
)
override fun createOutline(
size: Size,
layoutDirection: LayoutDirection,
density: Density,
): Outline {
return Outline.Generic(
// Draw your custom path here
path = drawTicketPath(
size = size,
density = density,
cornerTopStart = cornerTopStart,
cornerTopEnd = cornerTopEnd,
cornerBottomEnd = cornerBottomEnd,
cornerBottomStart = cornerBottomStart,
)
)
}
fun drawTicketPath(
size: Size,
density: Density,
cornerRadius: Dp,
): Path {
return drawTicketPath(
size = size,
density = density,
cornerTopStart = cornerRadius,
cornerTopEnd = cornerRadius,
cornerBottomEnd = cornerRadius,
cornerBottomStart = cornerRadius,
)
}
fun drawTicketPath(
size: Size,
density: Density,
cornerTopStart: Dp = 0.dp,
cornerTopEnd: Dp = 0.dp,
cornerBottomStart: Dp = 0.dp,
cornerBottomEnd: Dp = 0.dp,
): Path {
return Path().apply {
reset()
// Top left arc
with(density) {
val cornerTopStartPx = cornerTopStart.toPx()
val cornerTopEndPx = cornerTopEnd.toPx()
val cornerBottomEndPx = cornerBottomEnd.toPx()
val cornerBottomStartPx = cornerBottomStart.toPx()
arcTo(
rect = Rect(
left = -cornerTopStartPx,
top = -cornerTopStartPx,
right = cornerTopStartPx,
bottom = cornerTopStartPx
),
startAngleDegrees = 90.0f,
sweepAngleDegrees = -90.0f,
forceMoveTo = false
)
lineTo(x = size.width - cornerTopEndPx, y = 0f)
// Top right arc
arcTo(
rect = Rect(
left = size.width - cornerTopEndPx,
top = -cornerTopEndPx,
right = size.width + cornerTopEndPx,
bottom = cornerTopEndPx
),
startAngleDegrees = 180.0f,
sweepAngleDegrees = -90.0f,
forceMoveTo = false
)
lineTo(x = size.width, y = size.height - cornerBottomEndPx)
// Bottom right arc
arcTo(
rect = Rect(
left = size.width - cornerBottomEndPx,
top = size.height - cornerBottomEndPx,
right = size.width + cornerBottomEndPx,
bottom = size.height + cornerBottomEndPx
),
startAngleDegrees = 270.0f,
sweepAngleDegrees = -90.0f,
forceMoveTo = false
)
lineTo(x = cornerBottomStartPx, y = size.height)
// Bottom left arc
arcTo(
rect = Rect(
left = -cornerBottomStartPx,
top = size.height - cornerBottomStartPx,
right = cornerBottomStartPx,
bottom = size.height + cornerBottomStartPx
),
startAngleDegrees = 0.0f,
sweepAngleDegrees = -90.0f,
forceMoveTo = false
)
lineTo(x = 0f, y = cornerTopStartPx)
close()
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment