Jetpack Compose recently added lots of new customization options to TextStyle, TextStyle.drawStyle is one of them. Using this, we can apply stunning stroke effects to text in Jetpack Compose.
In this blog post, we’ll explore how to use DrawStyle API to create unique and creative stroke effects for texts.
So, if you’re ready to take your Jetpack Compose text designs to the next level, let’s dive in and explore DrawStyle API!
We are what we repeatedly do. Excellence, then, is not an act, but a habit. Try out Justly and start building your habits today!
We’ll use Stroke drawStyle, which provides information for drawing content with a stroke.
Let’s first look at what we have in Stroke API,
class Stroke(
val width: Float = 0.0f,
val miter: Float = DefaultMiter,
val cap: StrokeCap = DefaultCap,
val join: StrokeJoin = DefaultJoin,
val pathEffect: PathEffect? = null
) : DrawStyle() { }
Now Let’s implement cool Stroke Effects.
Text(
text = "Applying Cool Stroke Effects to Text",
style = LocalTextStyle.current.merge(
TextStyle(color = Color(0xFFF67C37),
fontSize = 80.sp,
drawStyle = Stroke(width = 6f, join = StrokeJoin.Round)
)
)
)
We just simply apply a stroke with a 6-pixel width and join to StrokeJoin.Round
Let’s chase the pathEffects
to implement different effects.. We’ll use cornerPathEffect
to round the sharp angle by radius. Here’s how,
Text(
text = "Applying Cool Stroke Effects to Text",
style = LocalTextStyle.current.merge(
TextStyle(
color = Color(0xFFF67C37),
fontSize = 80.sp,
drawStyle = Stroke(
width = 6f, join = StrokeJoin.Round,
pathEffect = PathEffect.cornerPathEffect(
radius = 40f
)
)
)
)
)
For dash stroke we have dashPathEffect
, which has intervals and phase params
intervals
— Array of “on” and “off” distances for the dashed line segmentsphase
— Pixel offset into the intervals arrayText(
text = "Applying Cool Stroke Effects to Text",
style = LocalTextStyle.current.merge(
TextStyle(
color = Color(0xFFF67C37),
fontSize = 80.sp,
drawStyle = Stroke(
width = 6f, join = StrokeJoin.Round,
pathEffect = PathEffect.dashPathEffect(
intervals = floatArrayOf(20f, 10f),
phase = 0f
)
)
)
)
)
Here’s the result
We can also apply multiple effects to outline paths using chainPathEffect
Let’s apply the dashed effect with the corner path.
@Composable
fun MultiplePathEffectDemo() {
val dashPathEffect = remember {
PathEffect.dashPathEffect(
intervals = floatArrayOf(20f, 10f),
0f
)
}
val cornerPathEffect = remember {
PathEffect.cornerPathEffect(
80f
)
}
Text(
text = "Applying Cool Stroke Effects to Text",
style = LocalTextStyle.current.merge(
TextStyle(
color = Color(0xFFF67C37),
fontSize = 80.sp,
drawStyle = Stroke(
width = 6f, join = StrokeJoin.Round,
pathEffect = PathEffect.chainPathEffect(dashPathEffect, cornerPathEffect)
)
)
)
)
}
Draw double outlines
val customPath = remember {
val p = Path()
p.moveTo(-15f, 6f)
p.lineTo(15f, 6f)
p.lineTo(15f, 2f)
p.lineTo(-15f, 2f)
p.close()
p.moveTo(-15f, -6f)
p.lineTo(15f, -6f)
p.lineTo(15f, -2f)
p.lineTo(-15f, -2f)
p
}
val stampEffect = remember {
PathEffect.stampedPathEffect(
customPath, 40f, 0f, StampedPathEffectStyle.Morph
)
}
Text(
text = "Applying Cool Stroke Effects to Text",
style = LocalTextStyle.current.merge(
TextStyle(
color = Color(0xFFF67C37),
fontSize = 80.sp,
drawStyle = Stroke(
width = 6f, join = StrokeJoin.Round,
pathEffect = stampEffect
)
)
)
)
Here we’ll use Brush API to add gradient stroke.
@Composable
fun GradientOutlineDemo() {
Text(
text = "Applying Cool Stroke Effects to Text",
style = LocalTextStyle.current.merge(
TextStyle(
fontSize = 80.sp,
brush = Brush.horizontalGradient(
listOf(
Color.Blue,
Color.Magenta,
Color.Red,
Color.Yellow
)
),
drawStyle = Stroke(
width = 6f, join = StrokeJoin.Round,
pathEffect = PathEffect.cornerPathEffect(
80f
)
)
)
)
)
}
Let’s have some fun with stroke effects.
We can draw different shapes using a path and stamp them on an outline using stampedPathEffect.
We’ll draw half circle shape and stamp on to outline. Here’s how
@Composable
fun CustomOutlineDemo() {
val customPath = Path().apply {
moveTo(-10f, 0f)
arcTo(
Rect(-10f, -10f, 10f, 10f),
180f,
180f,
false
);
}
val stampEffect = remember {
PathEffect.stampedPathEffect(
customPath, 20f, 0f, StampedPathEffectStyle.Morph
)
}
Text(
text = "Jetpack compose",
style = LocalTextStyle.current.merge(
TextStyle(
fontSize = 80.sp,
brush = Brush.horizontalGradient(
listOf(
Color.Blue,
Color.Magenta,
Color.Red,
Color.Yellow
)
),
drawStyle = Stroke(
width = 6f, join = StrokeJoin.Round,
pathEffect = stampEffect
)
)
)
)
}
@Composable
fun HeartShapeOutlineDemo() {
val heartPath = remember {
Path().apply {
val width = 20f
val height = 20f
moveTo(width / 2, height / 4)
cubicTo(width / 4, 0f, 0f, height / 3, width / 4, height / 2)
lineTo(width / 2, height * 3 / 4)
lineTo(width * 3 / 4, height / 2)
cubicTo(width, height / 3, width * 3 / 4, 0f, width / 2, height / 4)
}
}
val stampEffect = remember {
PathEffect.stampedPathEffect(
heartPath, 20f, 10f, StampedPathEffectStyle.Translate
)
}
Text(
text = "Jetpack compose",
style = LocalTextStyle.current.merge(
TextStyle(
fontSize = 80.sp,
brush = Brush.horizontalGradient(
listOf(
Color.Magenta,
Color.Red,
Color.Yellow
)
),
drawStyle = Stroke(
width = 10f,
pathEffect = stampEffect
)
)
)
)
}
In this blog post, we’ve explored the exciting world of DrawStyle API in Jetpack Compose and learned how to apply cool stroke effects to text.
We hope this post has inspired you to experiment with DrawStyle API in your own projects and create stunning text designs that will make your app stand out. Remember, the possibilities are endless when it comes to text styling in Jetpack Compose, and with the right tools and techniques, you can create designs that are both beautiful and functional.
Thank you for reading, and happy coding! 👋
Whether you need...