https://kotlinlang.org logo
#compose
Title
# compose
z

ziv kesten

06/20/2022, 1:13 PM
Does anyone have a good shadow modifier implementation? I use this:
Copy code
fun Modifier.advancedShadow(
    color: Color = Color.Black,
    alpha: Float = 0f,
    cornersRadius: Dp = 0.dp,
    shadowBlurRadius: Dp = 0.dp,
    offsetY: Dp = 0.dp,
    offsetX: Dp = 0.dp
) = drawBehind {

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

    drawIntoCanvas {
        val paint = Paint()
        val frameworkPaint = paint.asFrameworkPaint()
        frameworkPaint.color = transparentColor
        frameworkPaint.setShadowLayer(
            shadowBlurRadius.toPx(),
            offsetX.toPx(),
            offsetY.toPx(),
            shadowColor
        )
        it.drawRoundRect(
            0f,
            0f,
            this.size.width,
            this.size.height,
            cornersRadius.toPx(),
            cornersRadius.toPx(),
            paint
        )
    }
}
But it's not perfect.
👀 1
a

andrew

06/20/2022, 2:56 PM
Allow for passing in shape
m

mgrazianodecastro

09/08/2022, 1:54 AM
it feels good enough for most cases
a

andrew

09/08/2022, 1:56 AM
Copy code
fun Modifier.coloredShadow(
    color: Color,
    shape: Shape,
    alpha: Float = 0.2F,
    shadowRadius: Dp = 0.dp,
    offsetY: Dp = 0.dp,
    offsetX: Dp = 0.dp,
) = composed {
    val density = LocalDensity.current

    val shadowColor = remember(color, alpha) { color.copy(alpha).toArgb() }
    val paint = remember(shadowRadius, offsetX, offsetY, shadowColor, density) { Paint().apply {
        val frameworkPaint = asFrameworkPaint()

        with(density) {
            frameworkPaint.color = Color.Transparent.toArgb()
            frameworkPaint.setShadowLayer(
                shadowRadius.toPx(),
                offsetX.toPx(),
                offsetY.toPx(),
                shadowColor
            )
        }
    }}

    drawBehind {
        drawIntoCanvas {
            it.drawOutline(
                shape.createOutline(size, layoutDirection, this),
                paint
            )
        }
    }
}
I think I was away from my desktop, this impl allows passing in shape
Or better yet:
Copy code
fun Modifier.coloredShadow(
    color: Color,
    shape: Shape,
    alpha: Float = 0.2F,
    shadowRadius: Dp = 0.dp,
    offsetY: Dp = 0.dp,
    offsetX: Dp = 0.dp,
) = coloredShadow(color, shape, alpha, shadowRadius, DpOffset(offsetX, offsetY))

fun Modifier.coloredShadow(
    color: Color,
    shape: Shape,
    alpha: Float = 0.2F,
    shadowRadius: Dp = 0.dp,
    offset: DpOffset = DpOffset(0.dp, 0.dp),
) = composed {
    val density = LocalDensity.current

    val shadowColor = remember(color, alpha) { color.copy(alpha).toArgb() }
    val paint = remember(shadowRadius, offset.x, offset.y, shadowColor, density) { Paint().apply {
        val frameworkPaint = asFrameworkPaint()

        with(density) {
            frameworkPaint.color = Color.Transparent.toArgb()
            frameworkPaint.setShadowLayer(
                shadowRadius.toPx(),
                offset.x.toPx(),
                offset.y.toPx(),
                shadowColor
            )
        }
    }}

    drawBehind {
        drawIntoCanvas {
            it.drawOutline(
                shape.createOutline(size, layoutDirection, this),
                paint
            )
        }
    }
}
Quick DpOffset overload
7 Views