I want to draw a text using Canvas
.
here is my code:
val firstOffset = Offset(x = 0F, y = 0F)
val secondOffset = Offset(x = 0F, y = 1000F)
val thirdOffset = Offset(x = 0F, y = 1080F)
Canvas(
modifier = Modifier.width(priceBarItemWidth)
.fillMaxHeight()
.pointerHoverIcon(
PointerIcon(Cursor(N_RESIZE_CURSOR))
)
) {
drawText(
textMeasurer = textMeasurer,
text = "qwerty",
topLeft = firstOffset,
style = style
)
}
when I use firstOffset
text goes to top left of screen
when I use secondOffset
text goes to bottom left of screen
and when I use thirdOffset
i get this error:
Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException:
maxHeight(-30) must be >= than minHeight(0)
I want to draw this text out of screen (I want to develop a scrollable list using Canvas and I know there is better ways to do this) so the question is how can I draw texts out of screen to bring scroll function to my custom list!
and the original code is below:
val containerSize by service.containerSize.collectAsState()
Canvas(
modifier = Modifier.width(priceBarItemWidth)
.fillMaxHeight()
.pointerHoverIcon(
PointerIcon(Cursor(N_RESIZE_CURSOR))
)
) {
if (containerSize.height == 0) return@Canvas
var currentHeight = 25 * (priceBarItemHeightInPx +
priceBarSpaceBetweenItemInPx)
prices.forEachIndexed { index, fl ->
drawText(
textMeasurer = textMeasurer,
text = fl.toString(),
topLeft = Offset(x = 0F, y = 0F),
style = style
)
currentHeight -= (priceBarItemHeightInPx + priceBarSpaceBetweenItemInPx)
}
}
This happens due to drawText function passing Constraints with negative height in calculation here.
Passing topLeft with bigger than text height, when you don't set size
param of drawText
, returns negative maxHeight which is not allowed. Passing smaller maxHeight than minHeight also not allowed for Constraints as well.
You can set size
param of drawText
function or you can use translate
function of DrawScope as
@Preview
@Composable
private fun CanvasTextSample() {
val list = remember {
listOf(
"Hello",
"World",
"Text1",
"Text2",
"Text3",
"Text4",
)
}
Column(
modifier = Modifier.padding(16.dp).fillMaxSize().padding(top = 60.dp)
) {
val textMeasurer = rememberTextMeasurer()
var offset by remember {
mutableStateOf(0f)
}
Canvas(
modifier = Modifier
.pointerInput(Unit) {
detectDragGestures { change, dragAmount ->
offset += dragAmount.y
}
}
.fillMaxWidth()
.aspectRatio(1f)
.border(1.dp, Color.Red)
) {
list.fastForEachIndexed { index, text ->
translate(
left = 100f,
top = offset + index * 20.dp.toPx()
) {
drawText(
textMeasurer = textMeasurer,
text = text,
)
}
}
}
}
}
If you wish to center Text horizontally inside Canvas use textMeasurer.measure() to get TextLayoutResult and center Text using size returned from it and Canvas size.