How can we manage text width while changing its X-offset in jetpack compose?

Viewed 244

I want to manage the width of the text along with the size of the screen when changing the x-offset of the text. If I'm changing the x-offset of the text it is going out of the screen, So I wish that if it goes off the screen it should wrap that text and take it to a new line.

As you can see in this image it is showing proper because text is not that long.

This works fine when text is short

But as soon as text get longer it is getting out of screen.

Here is my code for reference

var textCoordinate: LayoutCoordinates? by remember { mutableStateOf(null) }
var outerRadius by remember { mutableStateOf(0f) }
val topArea = 100.dp
val screenHeight = LocalConfiguration.current.screenHeightDp
val textYOffset = with(LocalDensity.current) {
    targets.coordinates.positionInRoot().y.toDp()
}
var outerOffset by remember { mutableStateOf(Offset(0f, 0f)) }

textCoordinate?.let {
    val textRect = it.boundsInRoot()
    val textHeight = it.size.height
    val isInGutter = topArea > textYOffset || textYOffset > screenHeight.dp.minus(topArea)
    outerOffset =
        getOuterCircleCenter(targetRect, textRect, targetRadius, textHeight, isInGutter)
    outerRadius = getOuterRadius(textRect, targetRect) + targetRadius
}

Canvas(
    modifier = Modifier
        .fillMaxSize()
        .pointerInput(targets) {
            detectTapGestures { tapOffset ->
                if (targetRect.contains(tapOffset)) {
                    onShowCaseCompleted()
                }
            }
        }
        .graphicsLayer(alpha = 0.99f)
) {
    when (targets.showCaseType) {
        /**
         * Rounded ShowCaseView
         */
        ShowCaseType.SIMPLE_ROUNDED -> {
            drawCircle(
                color = Color.Black,
                radius = size.maxDimension,
                alpha = 0.9f
            )
            drawCircle(
                color = Color.White,
                radius = targetRadius - 10f,
                center = targetRect.center,
                blendMode = BlendMode.Clear
            )
        }
        /**
         * Rectangle ShowCaseView
         */
        ShowCaseType.SIMPLE_RECTANGLE -> {
            drawRect(
                Color.Black.copy(alpha = 0.6f),
                size = Size(size.width + 40f, size.height + 40f),
                style = Fill,
            )
            drawRect(
                Color.White,
                size = Size(rectSize.width + 15f, rectSize.height + 15f),
                style = Fill,
                topLeft = Offset(xOffset - 8, yOffset - 8),
                blendMode = BlendMode.Clear
            )
        }
        /**
         * Rounded ShowCaseView with animation
         */
        ShowCaseType.ANIMATE_ROUNDED -> {
            drawCircle(
                color = Color.Black,
                center = outerOffset,
                radius = outerRadius * outerAnimaTable.value,
                alpha = 0.9f
            )
            // draw circle with animation
            dys.forEach { dy ->
                drawCircle(
                    color = Color.White,
                    radius = targetRect.maxDimension * dy * 2f,
                    center = targetRect.center,
                    alpha = 1 - dy
                )
            }
            drawCircle(
                color = Color.White,
                radius = targetRadius,
                center = targetRect.center,
                blendMode = BlendMode.Clear
            )
        }
    }
}

    @Composable
fun ShowText(
    currentTarget: ShowcaseProperty,
    targetRect: Rect,
    targetRadius: Float,
    updateCoordinates: (LayoutCoordinates) -> Unit
) {
    var txtOffsetY by remember { mutableStateOf(0f) }
    var txtOffsetX by remember { mutableStateOf(0f) }
    val configuration = LocalConfiguration.current
    val screenWidth = configuration.screenWidthDp.toFloat()

    Column(modifier = Modifier
        .offset(
            x = with(LocalDensity.current) { txtOffsetX.toDp() },
            y = with(LocalDensity.current) { txtOffsetY.toDp() }
        )
        .onGloballyPositioned {
            updateCoordinates(it)
            val textHeight = it.size.height
            val possibleTop =
                targetRect.center.y - targetRadius - textHeight
            val possibleLeft = targetRect.topLeft.x
            txtOffsetY = if (possibleTop > 0) {
                possibleTop
            } else {
                targetRect.center.y + targetRadius - 140
            }
            txtOffsetX = it.boundsInRoot().topRight.x - it.size.width
            txtOffsetX = if (possibleLeft >= screenWidth / 2) {
                screenWidth / 2 + targetRadius
            } else {
                possibleLeft
            }
        }
        .padding(2.dp)
    ) {
        Text(
            text = currentTarget.title,
            fontSize = 20.sp,
            fontWeight = FontWeight.Bold,
            color = Color.Blue
        )
        Text(
            text = currentTarget.subTitle,
            fontSize = 14.sp,
            color = Color.Blue,

        )
    }
}

How can we manage this? is there any way?

0 Answers
Related