Reputation: 618
Is it possible to apply a cap to only one of the two ends of a stroke while drawing in a Compose Canvas DrawScope context?
Upvotes: 2
Views: 1308
Reputation: 87794
There is no built-in solution.
I could not find a solution for android.graphics.Canvas
either: if you know how to do it in plain android canvas, you can use it in compose c with drawIntoCanvas
.
The only approach I can think of is to draw the caps on top:
fun DrawScope.drawLine(
color: Color,
start: Offset,
end: Offset,
strokeWidth: Float = Stroke.HairlineWidth,
startCap: StrokeCap,
endCap: StrokeCap,
) {
drawLine(
color = color,
start = start,
end = end,
strokeWidth = strokeWidth,
cap = StrokeCap.Butt,
)
listOf(
Triple(start, end, startCap),
Triple(end, start, endCap),
).forEach {
drawCap(
color = color,
start = it.first,
end = it.second,
strokeWidth = strokeWidth,
cap = it.third
)
}
}
private fun DrawScope.drawCap(
color: Color,
start: Offset,
end: Offset,
strokeWidth: Float = Stroke.HairlineWidth,
cap: StrokeCap,
) {
when (cap) {
StrokeCap.Butt -> Unit
StrokeCap.Round -> {
drawCircle(color, center = start, radius = strokeWidth / 2)
}
StrokeCap.Square -> {
val offset = Offset(strokeWidth / 2, strokeWidth / 2)
val size = Size(strokeWidth, strokeWidth)
rotateRad(
radians = (end - start).run { atan2(x, y) },
pivot = start
) {
drawRect(color, topLeft = start - offset, size = size)
}
}
}
}
Calculating angle in case for a line in StrokeCap.Square
is pretty simple, but if you need this for curves the solution may not be that easy.
But in you only need to support StrokeCap.Round
knowing the start/end points and stroke width will be enough.
Upvotes: 2