Skip to content

Instantly share code, notes, and snippets.

@BadrAtt
Created October 1, 2025 21:44
Show Gist options
  • Select an option

  • Save BadrAtt/5ccddf5b1f429089338a7c1ba5633133 to your computer and use it in GitHub Desktop.

Select an option

Save BadrAtt/5ccddf5b1f429089338a7c1ba5633133 to your computer and use it in GitHub Desktop.
Football ground in jetpack compose
val pitchLightColor = Color(0XFF5b9452)
val pitchDarkColor = Color(0XFF3F7A39)
@Composable
fun FootballGroundScreen(modifier: Modifier = Modifier) {
val lineLength = 4f
//standard measures in meter
val pitchRectanglesCount = 12
val pitchLengthMeters = 105f
val pitchWidthMeters = 68f
val penaltyAreaWidth = 40.2f
val penaltyAreaLength = 16.5f
val goalAreaWidth = 18.3f
val goalAreaLength = 5.5f
Canvas(
modifier = modifier
.fillMaxSize()
.background(Color.Transparent)
.drawBehind {
drawRect(
color = pitchLightColor,
)
}
) {
inset(horizontal = 50f, vertical = 50f) {
val rectangleHeight = (size.height / pitchRectanglesCount).roundToInt()
val scaleX = size.width / pitchWidthMeters
val scaleY = size.height / pitchLengthMeters
val scale = min(scaleX, scaleY)
val centerCircleRadiusPx = 9.15f * scale
val centerSpotRadiusPx = (0.4f) * scale
repeat(pitchRectanglesCount) { index ->
val yOffset = index * rectangleHeight.toFloat()
if (index % 2 == 0) {
drawRect(
color = pitchLightColor,
topLeft = Offset(0f, yOffset),
size = Size(size.width, rectangleHeight.toFloat())
)
} else {
drawRect(
color = pitchDarkColor,
topLeft = Offset(0f, yOffset),
size = Size(size.width, rectangleHeight.toFloat())
)
}
}
//Main area
drawRect(
color = Color.White,
size = Size(size.width, size.height),
style = Stroke(width = lineLength)
)
//Center line
drawLine(
color = Color.White,
start = Offset(x = 0f, y = size.height / 2),
end = Offset(x = size.width, y = size.height / 2),
strokeWidth = 5f
)
// Center circle
drawCircle(
color = Color.White,
radius = centerCircleRadiusPx,
center = center,
style = Stroke(width = lineLength)
)
// Center spot
drawCircle(
color = Color.White,
radius = centerSpotRadiusPx,
center = center,
style = Fill
)
val cornerArcRadius = 6f * scale
//top left arc
drawArc(
color = Color.White,
startAngle = 0f,
sweepAngle = 90f,
useCenter = false,
size = Size(cornerArcRadius, cornerArcRadius),
topLeft = Offset(-cornerArcRadius /2, -cornerArcRadius / 2),
style = Stroke(lineLength)
)
//top right arc
drawArc(
color = Color.White,
startAngle = 90f,
sweepAngle = 90f,
useCenter = false,
size = Size(cornerArcRadius, cornerArcRadius),
topLeft = Offset(size.width - (cornerArcRadius / 2), -cornerArcRadius / 2),
style = Stroke(lineLength)
)
//bottom right arc
drawArc(
color = Color.White,
startAngle = 180f,
sweepAngle = 90f,
useCenter = false,
size = Size(cornerArcRadius, cornerArcRadius),
topLeft = Offset(
size.width - (cornerArcRadius / 2),
size.height - (cornerArcRadius / 2)
),
style = Stroke(lineLength)
)
//bottom left arc
drawArc(
color = Color.White,
startAngle = 270f,
sweepAngle = 90f,
useCenter = false,
size = Size(cornerArcRadius, cornerArcRadius),
topLeft = Offset(-cornerArcRadius / 2, size.height - cornerArcRadius / 2),
style = Stroke(lineLength)
)
val penaltyAreaTopLeft = (size.width - (penaltyAreaWidth * scale)) / 2
//top penalty area
drawRect(
color = Color.White,
size = Size(width = penaltyAreaWidth * scale, height = penaltyAreaLength * scale),
topLeft = Offset(penaltyAreaTopLeft, 0f),
style = Stroke(lineLength)
)
val arcWidth = 9.5f
val arcHeight = arcWidth / 2
//top penalty arc
drawArc(
color = Color.White,
startAngle = 0f,
sweepAngle = 180f,
useCenter = false,
size = Size(arcWidth * scale, arcHeight * scale),
topLeft = Offset(
size.width.div(2).minus(arcWidth * scale / 2),
penaltyAreaLength * scale - arcHeight * scale / 2
),
style = Stroke(lineLength)
)
//bottom penalty arc
drawArc(
color = Color.White,
startAngle = 180f,
sweepAngle = 180f,
useCenter = false,
size = Size(arcWidth * scale, arcHeight * scale),
topLeft = Offset(
size.width.div(2).minus(arcWidth * scale / 2),
size.height.minus(penaltyAreaLength * scale + arcHeight * scale / 2)
),
style = Stroke(lineLength)
)
//bottom left arc
drawArc(
color = Color.White,
startAngle = 270f,
sweepAngle = 90f,
useCenter = false,
size = Size(cornerArcRadius, cornerArcRadius),
topLeft = Offset(-cornerArcRadius / 2, size.height - cornerArcRadius / 2),
style = Stroke(lineLength)
)
//top goal Area
val goalAreaTopLeft = (size.width - (goalAreaWidth * scale)) / 2
drawRect(
color = Color.White,
size = Size(width = goalAreaWidth * scale, height = goalAreaLength * scale),
topLeft = Offset(goalAreaTopLeft, 0f),
style = Stroke(lineLength)
)
//bottom penalty area
drawRect(
color = Color.White,
size = Size(width = penaltyAreaWidth * scale, height = penaltyAreaLength * scale),
topLeft = Offset(penaltyAreaTopLeft, size.height - (penaltyAreaLength * scale)),
style = Stroke(lineLength)
)
//bottom goal Area
drawRect(
color = Color.White,
size = Size(width = goalAreaWidth * scale, height = goalAreaLength * scale),
topLeft = Offset(goalAreaTopLeft, size.height - (goalAreaLength * scale)),
style = Stroke(lineLength)
)
// top penalty Area Spot
drawCircle(
color = Color.White,
radius = centerSpotRadiusPx,
center = Offset(x = size.width / 2, 11f * scale),
style = Fill
)
// top penalty Area Spot
drawCircle(
color = Color.White,
radius = centerSpotRadiusPx,
center = Offset(x = size.width / 2, (size.height - 11f * scale)),
style = Fill
)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment