Add drop shadow to svg vector image in jetpack compose

2.4k Views Asked by At

I have a white arrow svg vector set in Image inside Box to which I want to add drop shadow so that it could be visible in white background too. Below is how it would look like:

enter image description here

This is the arrow to which I want to add drop shadow:

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="16dp"
    android:height="16dp"
    android:viewportWidth="16"
    android:viewportHeight="16">
  <group>
    <clip-path
        android:pathData="M16,16l-16,-0l-0,-16l16,-0z"/>
    <path
        android:pathData="M10.6667,13.333L5.3333,7.9997L10.6667,2.6663"
        android:strokeLineJoin="round"
        android:strokeWidth="1.5"
        android:fillColor="#00000000"
        android:strokeColor="#000"
        android:strokeLineCap="round"/>
  </group>
</vector>

The drop shadow values to be added are:

box-shadow: 0px 0px 6px 0px #00000040;

I tried using shadow in modifier but it did not work properly

            Image(
                modifier = Modifier
                    .align(Alignment.CenterEnd)
                    .shadow(60.dp, RoundedCornerShape(6.dp))
                    .clickable {
                        coroutineScope.launch {
                            shouldAutoScroll = false
                            pagerState.animateScrollToPage(
                                page = (pagerState.currentPage + 1) % (pagerState.pageCount)
                            )
                        }
                    },
                painter = painterResource(id = R.drawable.ic_right_arrow),
                contentDescription = stringResource(id = R.string.image_thumbnail),
                colorFilter = ColorFilter.tint(roposoModel.arrowColor)
            )

Could somebody help me to understand how can I achieve this?

2

There are 2 best solutions below

0
On

The best I've achieved is a "simulation: of the shadow duplicating the icon and applying some transformations, like this:

Box{
        Icon(
            imageVector = Icons.Default.ArrowForward,
            contentDescription = null,
            Modifier
                .offset(x = (-1).dp, y = (1).dp)
                .blur(4.dp),
            tint = Color.Black
            )
            Icon(
                imageVector = Icons.Default.ArrowForward,
                contentDescription = null,
                tint = Color.White
            )
}

It looks like this: enter image description here

Which can be tuned using the blur modifier and tint parameter.

0
On

You can specify a custom shape for the shadow in the shadow-modifier in the compose-code via the shape-parameter:

            Image(
                modifier = Modifier
                    .size(50.dp)
                    .align(Alignment.Center)
                    .shadow(
                        elevation = 5.dp,
                        shape = GenericShape { size, _ ->
                            moveTo(0f, 0f)
                            relativeLineTo(0f, size.height)
                            relativeLineTo(size.width, -size.height / 2f)
                            close()
                        },
                    )
                    .clickable { onClick() },
                painter = painterResource(
                    id = R.drawable.ic_gallery_video_overlay
                ),
                contentDescription = null,
            )

I did this for a play-icon triangle after studying this article to explain vector-drawable commands.

The result looks like this for the orange-bordered triangle in the middle:

enter image description here