transform card's shape in jetpack compose

557 Views Asked by At

can anyone tell me how to create below shape in jetpack compose

enter image description here

Thank you in advance

2

There are 2 best solutions below

2
On BEST ANSWER

You can also do like this , there is no need to create custom shape

@Composable
fun CustomCard() {

    Card(
        modifier = Modifier
            .height(300.dp)
            .width(600.dp)
            .padding(20.dp)
            .graphicsLayer {
                this.transformOrigin = TransformOrigin(0f, 0f)
                this.rotationY = 7f
            },
        border = BorderStroke(3.dp, Color(0xff5d6474)),
        backgroundColor = Color(0xff333d51), shape = RoundedCornerShape(80f)
    ) {

    }

}

In the graphics layer , just rotate the y-axis.

0
On

CustomShape inspired from https://juliensalvi.medium.com/custom-shape-with-jetpack-compose-1cb48a991d42

Its a extension of adding a paths with lines and arc.

For the transformation its just a rotation on y axis https://developer.android.com/jetpack/compose/graphics/draw/modifiers

A rounded border and a custom shape for background along with graphics layer that does rotation on y axis.

class CustomCardShape(private val radius: Float) : Shape {
    override fun createOutline(
        size: Size,
        layoutDirection: LayoutDirection,
        density: Density
    ): Outline {
        return Outline.Generic(
            path = drawCardShape(size, radius)
        )
    }
}

The shape with path

fun drawCardShape(size: Size, cornerRadius: Float): Path {
    return Path().apply {
        reset()
        // Top left arc
        arcTo(
            rect = Rect(
                left = 0f,
                top = 0f,
                right = cornerRadius,
                bottom = cornerRadius
            ),
            startAngleDegrees = 180.0f,
            sweepAngleDegrees = 90.0f,
            forceMoveTo = false
        )
        lineTo(x = size.width - cornerRadius, y = 0f)
        // Top right arc
        arcTo(
            rect = Rect(
                left = size.width - cornerRadius,
                top = 0f,
                right = size.width,
                bottom = cornerRadius
            ),
            startAngleDegrees = 270.0f,
            sweepAngleDegrees = 90.0f,
            forceMoveTo = false
        )
        lineTo(x = size.width, y = size.height - cornerRadius)
        // Bottom right arc
        arcTo(
            rect = Rect(
                left = size.width - cornerRadius,
                top = size.height - cornerRadius,
                right = size.width,
                bottom = size.height
            ),
            startAngleDegrees = 0.0f,
            sweepAngleDegrees = 90.0f,
            forceMoveTo = false
        )
        lineTo(x = cornerRadius, y = size.height)
        // Bottom left arc
        arcTo(
            rect = Rect(
                left = 0f,
                top = size.height - cornerRadius,
                right = cornerRadius,
                bottom = size.height
            ),
            startAngleDegrees = 90.0f,
            sweepAngleDegrees = 90.0f,
            forceMoveTo = false
        )
        lineTo(x = 0f, y = cornerRadius)
        close()
    }
}

The card composable

   Card(modifier = modifier
        .height(300.dp)
        .width(400.dp)
        .graphicsLayer {
            // pivot of where the rotation shud happen
            this.transformOrigin = TransformOrigin(0f, 0f)
            this.rotationY = 5f
        }.shadow(elevation = 4.dp, shape = CustomCardShape(80f),
            ambientColor  = Color(0xff2f5e9b),
            spotColor = Color(0xff2f5e9b)),
        border = BorderStroke(5.dp,Color(0xff5d6474)),
        backgroundColor = Color(0xff333d51),shape = CustomCardShape(80f)){

    }

Result

Card Composable with shape

The above might not be exactly like in the screen shot, however you can play with values to have it exactly like you want.