# basicMarquee

Common/AllAndroid/JVM

## Functions summary

|---|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/ui/Modifier` | `https://developer.android.com/reference/kotlin/androidx/compose/ui/Modifier.https://developer.android.com/reference/kotlin/androidx/compose/foundation/basicMarquee.modifier#(androidx.compose.ui.Modifier).basicMarquee(kotlin.Int,androidx.compose.foundation.MarqueeAnimationMode,kotlin.Int,kotlin.Int,androidx.compose.foundation.MarqueeSpacing,androidx.compose.ui.unit.Dp)( iterations: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html, animationMode: https://developer.android.com/reference/kotlin/androidx/compose/foundation/MarqueeAnimationMode, repeatDelayMillis: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html, initialDelayMillis: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html, spacing: https://developer.android.com/reference/kotlin/androidx/compose/foundation/MarqueeSpacing, velocity: https://developer.android.com/reference/kotlin/androidx/compose/ui/unit/Dp )` Applies an animated marquee effect to the modified content if it's too wide to fit in the available space. | Cmn |

## Functions

### Modifier.basicMarquee

Cmn Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/BasicMarquee.kt+function:basicMarquee) Added in [1.10.0](https://developer.android.com/jetpack/androidx/releases/compose-foundation#1.10.0)

```
fun Modifier.basicMarquee(
    iterations: Int = Iterations,
    animationMode: MarqueeAnimationMode = Immediately,
    repeatDelayMillis: Int = RepeatDelayMillis,
    initialDelayMillis: Int = if (animationMode == Immediately) repeatDelayMillis else 0,
    spacing: MarqueeSpacing = Spacing,
    velocity: Dp = Velocity
): Modifier
```

Applies an animated marquee effect to the modified content if it's too wide to fit in the available space. This modifier has no effect if the content fits in the max constraints. The content will be measured with unbounded width.

When the animation is running, it will restart from the initial state any time:

- any of the parameters to this modifier change, or

- the content or container size change.

The animation only affects the drawing of the content, not its position. The offset returned by the `https://developer.android.com/reference/kotlin/androidx/compose/ui/layout/LayoutCoordinates` of anything inside the marquee is undefined relative to anything outside the marquee, and may not match its drawn position on screen. This modifier also does not currently support content that accepts position-based input such as pointer events.

To only animate when the composable is focused, specify `https://developer.android.com/reference/kotlin/androidx/compose/foundation/package-summary#(androidx.compose.ui.Modifier).basicMarquee(kotlin.Int,androidx.compose.foundation.MarqueeAnimationMode,kotlin.Int,kotlin.Int,androidx.compose.foundation.MarqueeSpacing,androidx.compose.ui.unit.Dp)` and make the composable focusable. This modifier does not add any visual effects aside from scrolling, but you can add your own by placing modifiers before this one.

```kotlin
import androidx.compose.foundation.basicMarquee
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.width
import androidx.compose.material3.Text
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp

// Marquee only animates when the content doesn't fit in the max width.
Column(Modifier.width(30.dp)) { Text("hello world", Modifier.basicMarquee()) }
```

```kotlin
import androidx.compose.foundation.MarqueeSpacing
import androidx.compose.foundation.basicMarquee
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.widthIn
import androidx.compose.material3.Text
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.drawWithContent
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.BlendMode
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.CompositingStrategy
import androidx.compose.ui.graphics.drawscope.ContentDrawScope
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.unit.dp

val edgeWidth = 32.dp
fun ContentDrawScope.drawFadedEdge(leftEdge: Boolean) {
    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,
    )
}

Text(
    "the quick brown fox jumped over the lazy dogs",
    Modifier.widthIn(max = edgeWidth * 4)
        // Rendering to an offscreen buffer is required to get the faded edges' alpha to be
        // applied only to the text, and not whatever is drawn below this composable (e.g. the
        // window).
        .graphicsLayer { compositingStrategy = CompositingStrategy.Offscreen }
        .drawWithContent {
            drawContent()
            drawFadedEdge(leftEdge = true)
            drawFadedEdge(leftEdge = false)
        }
        .basicMarquee(
            // Animate forever.
            iterations = Int.MAX_VALUE,
            spacing = MarqueeSpacing(0.dp),
        )
        .padding(start = edgeWidth),
)
```

```kotlin
import androidx.compose.foundation.MarqueeAnimationMode
import androidx.compose.foundation.basicMarquee
import androidx.compose.foundation.clickable
import androidx.compose.foundation.focusable
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.width
import androidx.compose.material3.Text
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.unit.dp

val focusRequester = remember { FocusRequester() }

// Marquee only animates when the content doesn't fit in the max width.
Column(Modifier.width(30.dp)) {
    Text(
        "hello world",
        Modifier.clickable { focusRequester.requestFocus() }
            .basicMarquee(animationMode = MarqueeAnimationMode.WhileFocused)
            .focusRequester(focusRequester)
            .focusable(),
    )
}
```

| Parameters |
|---|---|
| `iterations: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html = Iterations` | The number of times to repeat the animation. `Int.MAX_VALUE` will repeat forever, and 0 will disable animation. |
| `animationMode: https://developer.android.com/reference/kotlin/androidx/compose/foundation/MarqueeAnimationMode = Immediately` | Whether the marquee should start animating `https://developer.android.com/reference/kotlin/androidx/compose/foundation/MarqueeAnimationMode#Immediately()` or only `https://developer.android.com/reference/kotlin/androidx/compose/foundation/MarqueeAnimationMode#WhileFocused()`. In `https://developer.android.com/reference/kotlin/androidx/compose/foundation/MarqueeAnimationMode#WhileFocused()` mode, the modified node or the content must be made `https://developer.android.com/reference/kotlin/androidx/compose/foundation/focusable.modifier#(androidx.compose.ui.Modifier).focusable(kotlin.Boolean,androidx.compose.foundation.interaction.MutableInteractionSource)`. Note that the `https://developer.android.com/reference/kotlin/androidx/compose/foundation/package-summary#(androidx.compose.ui.Modifier).basicMarquee(kotlin.Int,androidx.compose.foundation.MarqueeAnimationMode,kotlin.Int,kotlin.Int,androidx.compose.foundation.MarqueeSpacing,androidx.compose.ui.unit.Dp)` is part of the animation, so this parameter determines when that initial delay starts counting down, not when the content starts to actually scroll. |
| `repeatDelayMillis: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html = RepeatDelayMillis` | The duration to wait before starting each subsequent iteration, in millis. |
| `initialDelayMillis: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html = if (animationMode == Immediately) repeatDelayMillis else 0` | The duration to wait before starting the first iteration of the animation, in millis. By default, there will be no initial delay if `https://developer.android.com/reference/kotlin/androidx/compose/foundation/package-summary#(androidx.compose.ui.Modifier).basicMarquee(kotlin.Int,androidx.compose.foundation.MarqueeAnimationMode,kotlin.Int,kotlin.Int,androidx.compose.foundation.MarqueeSpacing,androidx.compose.ui.unit.Dp)` is `https://developer.android.com/reference/kotlin/androidx/compose/foundation/MarqueeAnimationMode#WhileFocused()`, otherwise the initial delay will be `https://developer.android.com/reference/kotlin/androidx/compose/foundation/package-summary#(androidx.compose.ui.Modifier).basicMarquee(kotlin.Int,androidx.compose.foundation.MarqueeAnimationMode,kotlin.Int,kotlin.Int,androidx.compose.foundation.MarqueeSpacing,androidx.compose.ui.unit.Dp)`. |
| `spacing: https://developer.android.com/reference/kotlin/androidx/compose/foundation/MarqueeSpacing = Spacing` | A `https://developer.android.com/reference/kotlin/androidx/compose/foundation/MarqueeSpacing` that specifies how much space to leave at the end of the content before showing the beginning again. |
| `velocity: https://developer.android.com/reference/kotlin/androidx/compose/ui/unit/Dp = Velocity` | The speed of the animation in dps / second. A positive velocity means that the marquee will animate in the direction of the current `https://developer.android.com/reference/kotlin/androidx/compose/ui/unit/LayoutDirection`. |