Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jetpack Compose inner shadow

How to create an inner shadow with Jetpack Compose? The gradient should run from black on the outside to transparent on the inside. Modifier.shadow() is just for outer shadows. Using negative elevation is not working.

like image 234
ya man Avatar asked Jul 17 '26 06:07

ya man


1 Answers

Position of Modifier.shadow relative to Modifier.background places shadow inside your component. Also you can create Modifier.drawWithContent and frameworkPaint a show with blur.

Column(
    modifier = Modifier
        .fillMaxSize()
        .padding(20.dp)
) {
    ComponentWithInnerShadow()
    Spacer(modifier = Modifier.height(12.dp))
    ComponentWithOuterShadow()
    Spacer(modifier = Modifier.height(12.dp))
    ComponentWithCustomInnerShadow()
}

@Composable private fun ComponentWithInnerShadow() {
    Column(
        modifier = Modifier
            .clip(RoundedCornerShape(5.dp))
            .background(Color.Yellow)
            .shadow(2.dp, shape = RoundedCornerShape(5.dp))
    ) {
        Text(text = "Hello World", modifier = Modifier.padding(12.dp))
    } }

@Composable
private fun ComponentWithOuterShadow() {
    Column(
        modifier = Modifier
            .shadow(2.dp, shape = RoundedCornerShape(5.dp))
            .background(Color.Yellow)

    ) {
        Text(text = "Hello World", modifier = Modifier.padding(12.dp))
    }
}

@Composable
private  fun ComponentWithCustomInnerShadow() {
    Column(
        modifier = Modifier.innerShadow()

    ) {
        Text(text = "Hello World", modifier = Modifier.padding(12.dp))
    }
}

And with composed modifier. I didn't set parameters just set arbitrary numbers you can set your own parameters, and set color if you want to. This one looks better than standard inner shadow though. You need to provide color for foreground and shape with this one either. I set color and drew Rounded rectangle for demonstration

fun Modifier.innerShadow() = composed(
    inspectorInfo = {

    },
    factory = {

        val paint = remember() {
            Paint()
        }

        val foregroundPaint = remember() {
            Paint().apply {
                color = Color.Yellow
            }
        }

        val frameworkPaint = remember {
            paint.asFrameworkPaint()
        }

        Modifier.drawWithContent {
            this.drawIntoCanvas {
                val color = Color.LightGray

                val radius = 2.dp.toPx()

                val shadowColor = color
                    .copy(alpha = .7f)
                    .toArgb()
                val transparent = color
                    .copy(alpha = 0f)
                    .toArgb()

                frameworkPaint.color = transparent

                frameworkPaint.setShadowLayer(
                    radius,
                    0f,
                    0f,
                    shadowColor
                )
                val shadowRadius = 4.dp.toPx()

                it.drawRoundRect(
                    left = 0f,
                    top = 0f,
                    right = this.size.width,
                    bottom = this.size.height,
                    radiusX = 5.dp.toPx(),
                    radiusY = 5.dp.toPx(),
                    paint = foregroundPaint
                )

                it.drawRoundRect(
                    left = 0f,
                    top = 0f,
                    right = this.size.width,
                    bottom = this.size.height,
                    radiusX = 5.dp.toPx(),
                    radiusY = 5.dp.toPx(),
                    paint = paint
                )

                it.drawRoundRect(
                    left = shadowRadius,
                    top = shadowRadius,
                    right = this.size.width - shadowRadius,
                    bottom = this.size.height - shadowRadius,
                    radiusX = 5.dp.toPx(),
                    radiusY = 5.dp.toPx(),
                    paint = foregroundPaint
                )
                drawContent()

            }
        }
    }
)

enter image description here

like image 188
Thracian Avatar answered Jul 19 '26 21:07

Thracian



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!