Reputation: 542
I would like to know if there some way to specify to Jetpack Compose plugin to remove default elevation from Image component, or the only wy is rebuild the image asset.
I have this:
Image(
painter = painterResource(id = if(sessionToken.isNotEmpty()) R.drawable.ic_disa_logo else R.drawable.ic_cepsa_logo),
contentDescription = "login_logo",
modifier = Modifier
.align(CenterHorizontally)
.fillMaxWidth()
Which show like this
As you can check the image have a elevatioon which I'm not adding to the component, so Should I recreate the asset, or is there some way to remove it.
Thanks in advance !
[EDIT]
As the suggestion I try to use a custom shape to hide the border of the image make an implementation of the solution like this:
val offset = with(LocalDensity.current){
4.dp.toPx()
}
val customCircleShape = GenericShape{ size: Size, layoutDirection: LayoutDirection ->
addOval(
Rect(
offset = Offset(
offset, offset
),
size = Size(
width = size.width - 2 * offset,
height = size.height - 2 * offset
)
)
)
}
Column(
verticalArrangement = Arrangement.Top,
modifier = Modifier
.clip(customCircleShape)
.shadow(4.dp, CircleShape)
.size(60.dp)
.background(Color.White)
) {
Image(
painter = painterResource(id = if (sessionToken.isNotEmpty()) R.drawable.ic_disa_logo else R.drawable.ic_cepsa_logo),
contentDescription = "login_logo",
modifier = Modifier
.align(Alignment.CenterHorizontally)
.fillMaxWidth()
.fillMaxHeight(0.25f)
.border(BorderStroke(2.dp, Color.White), CircleShape)
.background(Color.White)
)
}
But the border is still showing as the firts picture I added it
What Am I missing here?
[EDIT]
Doesn't matter how big a do the circle which supose to hide the shadow, don't do it.
I add the picture i'm using as reference.
[SOLUTION]
I make works doing this:
val offset = with(LocalDensity.current){
8.dp.toPx()
}
val customCircleShape = GenericShape { size: Size, layoutDirection: LayoutDirection ->
addOval(
Rect(
offset = Offset(
offset, offset
),
size = Size(
width = size.width - 2 * offset,
height = size.height - 2 * offset
)
)
)
}
Image(
painter = painterResource(id = if(sessionToken.isNotEmpty()) R.drawable.ic_disa_logo else R.drawable.ic_cepsa_logo),
contentDescription = "login_logo",
contentScale = ContentScale.FillBounds,
modifier = Modifier
.align(CenterHorizontally)
.padding(10.dp)
.background(Color.White)
.clip(customCircleShape)
.size(80.dp),
)
Upvotes: 1
Views: 609
Reputation: 67248
Since your logo can be contained inside a Circle you can do it in several ways.
1- Using a Path
and clipPath
function inside drawScope of Modifier.drawWithContent
.
2- Creating a custom Circle shape that has smaller dimensions as in option 1 and applying Modifier.clip(customShape)
3- Using BlendMode
with destination drawCircle inside Modifier.drawWithContent
.
Since i don't have you logo. I created an Image that draws a red Circle with some shadow.
@Preview
@Composable
private fun MyImage() {
Canvas(
modifier = Modifier
.shadow(4.dp, CircleShape)
.size(60.dp)
.background(Color.White)
) {
drawCircle(color = Color.Red, radius = size.width / 2 - 5.dp.toPx())
}
}
And implemented this Modifier as
@Preview
@Composable
fun Test() {
Column(modifier = Modifier.fillMaxSize()) {
Text(text = "Original")
MyImage()
Spacer(modifier = Modifier.height(10.dp))
val path = remember {
androidx.compose.ui.graphics.Path()
}
val offset = with(LocalDensity.current){
4.dp.toPx()
}
val customCircleShape = GenericShape{size: Size, layoutDirection: LayoutDirection ->
addOval(
Rect(
offset = Offset(
offset, offset
),
size = Size(
width = size.width - 2 * offset,
height = size.height - 2 * offset
)
)
)
}
Spacer(modifier = Modifier.height(10.dp))
Text(text = "Clip with Shape")
Box(modifier = Modifier.clip(customCircleShape)){
MyImage()
}
Spacer(modifier = Modifier.height(10.dp))
Text(text = "drawWithContent and clipPath")
Box(
modifier = Modifier.drawWithContent {
if (path.isEmpty) {
path.addOval(
oval = Rect(
offset = Offset(
offset, offset
),
size = Size(
width = size.width - 2 * offset,
height = size.height - 2 * offset
)
)
)
}
clipPath(path = path, clipOp = ClipOp.Intersect) {
[email protected]()
}
}
) {
MyImage()
}
}
}
Result
The trick is to create a Rect for oval that which has offsets in both directions.
For BlendMode
sample you can check out the link below. I clipped out an image and Button
to squircle shape.
How to clip or cut a Composable?
With the image provided it's as
Only used clip with custom shape option but other options can be applied either to clip and add your custom shadow as i did.
@Preview
@Composable
private fun Test() {
val offset = with(LocalDensity.current) {
8.dp.toPx()
}
val customCircleShape = GenericShape { size: Size, layoutDirection: LayoutDirection ->
addOval(
Rect(
offset = Offset(
offset, offset
),
size = Size(
width = size.width - 2 * offset,
height = size.height - 2 * offset
)
)
)
}
Column(
Modifier
.fillMaxSize()
.padding(20.dp)
) {
Text("ORIGINAL")
Image(
painter = painterResource(id = R.drawable.shell),
contentDescription = null,
contentScale = ContentScale.FillBounds,
)
Text("Clipped with Shape")
Image(
modifier = Modifier
.border(1.dp, Color.Green)
.clip(customCircleShape),
painter = painterResource(id = R.drawable.shell),
contentDescription = null,
contentScale = ContentScale.FillBounds
)
Text("With Size and attached Modifier.shadow after")
Image(
modifier = Modifier
.border(1.dp, Color.Green)
.padding(10.dp)
.shadow(6.dp, spotColor = Color.Cyan, shape = CircleShape)
.background(Color.White)
.clip(customCircleShape)
.size(80.dp),
painter = painterResource(id = R.drawable.shell),
contentDescription = null,
contentScale = ContentScale.FillBounds
)
}
}
Upvotes: 3
Reputation: 156
Have you considered trying to create a custom shadow effect?
modifier = Modifier
.size(100.dp)
.clip(CircleShape)
.shadow(elevation = 0.dp, shape = CircleShape)
Upvotes: 0