feat: replace bounce marquee with constant-speed ticker
Replaces BounceMarqueeText with TickerText that scrolls at a fixed 33 dp/s regardless of text length. Text scrolls left off-screen with a container-width gap before looping. Initial 1.5s delay lets the user read the beginning. Made-with: Cursor
This commit is contained in:
@@ -5,7 +5,6 @@ import android.content.res.Configuration
|
||||
import android.graphics.BitmapFactory
|
||||
import androidx.compose.animation.AnimatedContent
|
||||
import androidx.compose.animation.animateColorAsState
|
||||
import androidx.compose.animation.core.FastOutSlowInEasing
|
||||
import androidx.compose.animation.core.LinearEasing
|
||||
import androidx.compose.animation.core.RepeatMode
|
||||
import androidx.compose.animation.core.animateFloat
|
||||
@@ -447,12 +446,13 @@ private fun ArtworkImage(
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun BounceMarqueeText(
|
||||
private fun TickerText(
|
||||
text: String,
|
||||
style: TextStyle,
|
||||
color: Color,
|
||||
strokeColor: Color? = null,
|
||||
strokeWidth: Float = 2f,
|
||||
velocityDpPerSecond: Float = 33f,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
val density = LocalDensity.current
|
||||
@@ -475,25 +475,26 @@ private fun BounceMarqueeText(
|
||||
|
||||
if (overflowPx > 0f) {
|
||||
key(text) {
|
||||
val scrollMs = ((overflowPx / density.density) * 18f).toInt().coerceIn(2000, 8000)
|
||||
val pauseMs = 1500
|
||||
val totalMs = pauseMs + scrollMs + pauseMs + scrollMs
|
||||
val velocityPxPerMs = with(density) { velocityDpPerSecond.dp.toPx() } / 1000f
|
||||
val totalScrollPx = textWidthPx + containerWidthPx
|
||||
val scrollMs = (totalScrollPx / velocityPxPerMs).toInt()
|
||||
val initialDelayMs = 1500
|
||||
val durationMs = initialDelayMs + scrollMs
|
||||
|
||||
val transition = rememberInfiniteTransition(label = "marquee")
|
||||
val transition = rememberInfiniteTransition(label = "ticker")
|
||||
val offset by transition.animateFloat(
|
||||
initialValue = 0f,
|
||||
targetValue = 0f,
|
||||
animationSpec = infiniteRepeatable(
|
||||
animation = keyframes {
|
||||
durationMillis = totalMs
|
||||
durationMillis = durationMs
|
||||
0f at 0 using LinearEasing
|
||||
0f at pauseMs using FastOutSlowInEasing
|
||||
-overflowPx at (pauseMs + scrollMs) using LinearEasing
|
||||
-overflowPx at (pauseMs + scrollMs + pauseMs) using FastOutSlowInEasing
|
||||
0f at initialDelayMs using LinearEasing
|
||||
-totalScrollPx at durationMs using LinearEasing
|
||||
},
|
||||
repeatMode = RepeatMode.Restart
|
||||
),
|
||||
label = "bounce"
|
||||
label = "ticker"
|
||||
)
|
||||
|
||||
Box(
|
||||
@@ -575,7 +576,7 @@ private fun TrackInfoSection(
|
||||
overflow = TextOverflow.Ellipsis
|
||||
)
|
||||
Spacer(modifier = Modifier.height(6.dp))
|
||||
BounceMarqueeText(
|
||||
TickerText(
|
||||
text = trackText,
|
||||
style = trackStyle,
|
||||
color = trackColor,
|
||||
|
||||
Reference in New Issue
Block a user