Created
October 1, 2025 21:44
-
-
Save BadrAtt/5ccddf5b1f429089338a7c1ba5633133 to your computer and use it in GitHub Desktop.
Football ground in jetpack compose
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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