10
votes

Can't figure out how to add a gradient to a text with an inner shadow with a modifier in Jetpack Compose. To have something like this? Any ideas?

enter image description here

1

1 Answers

12
votes

So far jetpack compose doesn't provide text gradient and inner shadow out of the box. Hence need to paint it by yourself:

result image

@Composable
fun drawGradientText(name: String, modifier: Modifier = Modifier) {

    val paint = Paint().asFrameworkPaint()

    val gradientShader: Shader = LinearGradientShader(
        from = Offset(0f, 0f),
        to = Offset(0f, 400f),
        listOf(Color.Blue, Color.Cyan)
    )

    Canvas(modifier.fillMaxSize()) {
        paint.apply {
            isAntiAlias = true
            textSize = 400f
            typeface = Typeface.create(Typeface.DEFAULT, Typeface.BOLD)
            style = android.graphics.Paint.Style.FILL
            color = android.graphics.Color.parseColor("#cdcdcd")
            xfermode = PorterDuffXfermode(PorterDuff.Mode.DST_OVER)
            maskFilter = BlurMaskFilter(30f, Blur.NORMAL)
        }
        drawIntoCanvas { canvas ->
            canvas.save()
            canvas.nativeCanvas.translate(2f, 5f)
            canvas.nativeCanvas.drawText(name, 0f, 400f, paint)
            canvas.restore()
            paint.shader = gradientShader
            paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.CLEAR)
            paint.maskFilter = null
            canvas.nativeCanvas.drawText(name, 0f, 400f, paint)
            canvas.nativeCanvas.translate(2f, 5f)
            paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.DST_OVER)
            paint.maskFilter = BlurMaskFilter(30f, Blur.NORMAL)
            canvas.nativeCanvas.drawText(name, 0f, 400f, paint)
        }
        paint.reset()
    }
}

You can adjust PorterDuff modes and offsets to meet your requirements.