Hi, I am trying to create some UI in compose like ...
# compose
s
Hi, I am trying to create some UI in compose like this the closest I have reached is the second image does anyone know how can I create the shape properly (I am unable to create it) and here is the releavent code ``````
🧵 3
j
How are you going about creating the shape?
d
To make proper curve in compose, this function could be useful from shape class.
Copy code
/**
 * Adds a quadratic bezier segment that curves from the current
 * point to the given point ([x2], [y2]), using the control point
 * ([x1], [y1]).
 */
fun quadraticTo(x1: Float, y1: Float, x2: Float, y2: Float) {
    @Suppress("DEPRECATION")
    quadraticBezierTo(x1, y1, x2, y2)
}
👀 1
s
@Jonathan I am still in the process of drawing the curve and moreover integrating it to a button through the Shape class but giving a border to it is just havoc
j
Defining a custom shape using a Path is your best bet. You can then pass the custom shape to
Modifier.border(…)
to get it decorated like you would like.
âž• 1
Also, you never shared your code.
s
Thanks I got what i wanted to create here is the code thanks for the help
Copy code
@Composable
fun CubicCurveDemo(modifier: Modifier = Modifier) {
    Canvas(
        modifier = modifier
            .fillMaxWidth()
            .height(200.dp)
            .border(1.dp, Color.Black)
    ) {
        // Get the actual canvas dimensions
        val canvasWidth = size.width
        val canvasHeight = size.height

        // Define shape parameters as ratios of canvas dimensions
        val startY = canvasHeight * 0.75f // 75% from top
        val peakY = canvasHeight * 0.1f    // 10% from top (peak height)

        // Start more inward from left edge
        val start1 = Offset(canvasWidth * 0.0f, startY)

        // First curve control points - only TOP control point pushed outward
        val c1_1 = Offset(canvasWidth * 0.15f, startY) // Bottom control point - keep original position
        val c1_2 = Offset(canvasWidth * 0.18f, peakY)  // TOP control point - pushed MORE outward
        val end1 = Offset(canvasWidth * 0.40f, peakY)  // End of first curve (your desired 0.40f)

        // Straight section
        val straightLen = canvasWidth * 0.20f // Adjusted to 20% since we're using 0.40f for first curve
        val endStraight = Offset(end1.x + straightLen, end1.y)

        // Control points for straight section
        val straightCtrl1 = Offset(end1.x + straightLen / 3f, end1.y)
        val straightCtrl2 = Offset(end1.x + 2f * straightLen / 3f, end1.y)

        // Second curve control points - properly mirror the first curve
        // Mirror c1_2 around the center of the canvas
        val c2_1 = Offset(
            canvasWidth - (c1_2.x - canvasWidth * 0.0f), // Mirror c1_2 position relative to canvas width
            peakY
        )
        // Mirror c1_1 around the center of the canvas
        val c2_2 = Offset(
            canvasWidth - (c1_1.x - canvasWidth * 0.0f), // Mirror c1_1 position relative to canvas width
            startY
        )
        val end2 = Offset(canvasWidth, startY) // End at the very right edge

        val path = Path().apply {
            moveTo(start1.x, start1.y)

            // First curve
            cubicTo(c1_1.x, c1_1.y, c1_2.x, c1_2.y, end1.x, end1.y)

            // Straight section
            cubicTo(
                straightCtrl1.x, straightCtrl1.y,
                straightCtrl2.x, straightCtrl2.y,
                endStraight.x, endStraight.y
            )

            // Second mirrored curve
            cubicTo(
                c2_1.x, c2_1.y,
                c2_2.x, c2_2.y,
                end2.x, end2.y
            )

            // Close the path by connecting back to start
            lineTo(start1.x, start1.y)
            close()
        }

        val path2 = Path().apply {
            moveTo(start1.x, start1.y)

            // First curve
            cubicTo(c1_1.x, c1_1.y, c1_2.x, c1_2.y, end1.x, end1.y)

            // Straight section
            cubicTo(
                straightCtrl1.x, straightCtrl1.y,
                straightCtrl2.x, straightCtrl2.y,
                endStraight.x, endStraight.y
            )

            // Second mirrored curve
            cubicTo(
                c2_1.x, c2_1.y,
                c2_2.x, c2_2.y,
                end2.x, end2.y
            )

            // Close the path by connecting back to start
        }

        drawPath(
            path = path,
            color = Color.Black,
            style = Fill
        )
        drawPath(
            path = path2,
            color = Color.Red,
            style = Stroke(10f)
        )
    }
}
Here is the reference image of the shape