0

I have 2 texts, one that scrolls automatically with the basicMarquee effect (since it exceeds the width size and executes the effect) and the other, which does not exceed the width and does not execute the effect:

enter image description here

I have the text applied as follows:

fun ContentDrawScope.drawFadedEdge(
    leftEdge: Boolean,
    edgeWidth: Dp
) {
    val edgeWidthPx = edgeWidth.toPx()
    drawRect(
        topLeft = Offset(if (leftEdge) 0f else size.width - edgeWidthPx, 0f),
        size = Size(edgeWidthPx, size.height),
        brush = Brush.horizontalGradient(
            colors = listOf(Color.Transparent, Color.Black),
            startX = if (leftEdge) 0f else size.width,
            endX = if (leftEdge) edgeWidthPx else size.width - edgeWidthPx
        ),
        blendMode = BlendMode.DstIn
    )
}

@OptIn(ExperimentalFoundationApi::class)
@Composable
@NonRestartableComposable
fun MarqueeText(
    text: String,
    modifier: Modifier = Modifier,
    color: Color = Color.Unspecified,
    fontSize: TextUnit = TextUnit.Unspecified,
    fontStyle: FontStyle? = null,
    fontWeight: FontWeight? = null,
    fontFamily: FontFamily? = null,
    letterSpacing: TextUnit = TextUnit.Unspecified,
    textDecoration: TextDecoration? = null,
    textAlign: TextAlign? = TextAlign.Center,
    lineHeight: TextUnit = TextUnit.Unspecified,
    overflow: TextOverflow = TextOverflow.Clip,
    softWrap: Boolean = true,
    iterations: Int = Int.MAX_VALUE,
    edgeWidthGradient: Dp = 10.dp,
    marqueeSpacing: MarqueeSpacing = MarqueeSpacing(30.dp),
    delayMillis: Int = DefaultMarqueeDelayMillis,
    animationMode: MarqueeAnimationMode = MarqueeAnimationMode.Immediately,
    velocity: Dp = DefaultMarqueeVelocity,
    maxLines: Int = Int.MAX_VALUE,
    onTextLayout: (TextLayoutResult) -> Unit = {},
    style: TextStyle = LocalTextStyle.current
) = Text(
    text = text,
    modifier = modifier
        .fillMaxWidth()
        .graphicsLayer { compositingStrategy = CompositingStrategy.Offscreen }
        .drawWithContent {
            drawContent()
            drawFadedEdge(leftEdge = true, edgeWidth = edgeWidthGradient)
            drawFadedEdge(leftEdge = false, edgeWidth = edgeWidthGradient)
        }
        .basicMarquee(
            animationMode = animationMode,
            iterations = iterations,
            delayMillis = delayMillis,
            spacing = marqueeSpacing,
            velocity = velocity
        ),
    color = color,
    fontSize = fontSize,
    fontStyle = fontStyle,
    fontWeight = fontWeight,
    fontFamily = fontFamily,
    letterSpacing = letterSpacing,
    textDecoration = textDecoration,
    textAlign = textAlign,
    lineHeight = lineHeight,
    overflow = overflow,
    softWrap = softWrap,
    maxLines = maxLines,
    onTextLayout = onTextLayout,
    style = style
)

The aim would be that in case the text does not exceed the width, the text does not show the gradient on the start side when the text is aligned to the right.

I have tried with paddings and it works but the problem is that I don't want the text to have padding to avoid that, because in the view where I have that Text() has a padding that already displaces the text, so in the end it looks strange.

I need to know if this check can be done to avoid the gradient in texts that do not exceed the space and do not execute the effect and that in case of exceeding it if they do execute it and show the gradient.

Thank you in advance

Jéluchu
  • 394
  • 4
  • 13
  • 2
    `basicMarquee` itself does not support gradients and does not give you information about whether it scrolls or not. You can [create a feature request](https://issuetracker.google.com/u/1/issues/new?component=612128) - I don't think there's one already. For now, [my solution](https://stackoverflow.com/a/68980032/3585796) works as you would expect. – Phil Dukhov May 17 '23 at 04:43

0 Answers0