feat: add fade-in and shorten restart pause for ticker
Text now fades in over 300ms when it reappears instead of popping in. Restart pause shortened from 1.5s to 0.5s. Initial 1.5s delay kept. Switched from infiniteRepeatable to Animatable + LaunchedEffect loop for independent control over initial vs subsequent cycles. Made-with: Cursor
This commit is contained in:
@@ -5,13 +5,10 @@ import android.content.res.Configuration
|
|||||||
import android.graphics.BitmapFactory
|
import android.graphics.BitmapFactory
|
||||||
import androidx.compose.animation.AnimatedContent
|
import androidx.compose.animation.AnimatedContent
|
||||||
import androidx.compose.animation.animateColorAsState
|
import androidx.compose.animation.animateColorAsState
|
||||||
|
import androidx.compose.animation.core.Animatable
|
||||||
import androidx.compose.animation.core.LinearEasing
|
import androidx.compose.animation.core.LinearEasing
|
||||||
import androidx.compose.animation.core.RepeatMode
|
|
||||||
import androidx.compose.animation.core.animateFloat
|
|
||||||
import androidx.compose.animation.core.infiniteRepeatable
|
|
||||||
import androidx.compose.animation.core.keyframes
|
|
||||||
import androidx.compose.animation.core.rememberInfiniteTransition
|
|
||||||
import androidx.compose.animation.core.tween
|
import androidx.compose.animation.core.tween
|
||||||
|
import kotlinx.coroutines.delay
|
||||||
import androidx.compose.animation.fadeIn
|
import androidx.compose.animation.fadeIn
|
||||||
import androidx.compose.animation.fadeOut
|
import androidx.compose.animation.fadeOut
|
||||||
import androidx.compose.animation.togetherWith
|
import androidx.compose.animation.togetherWith
|
||||||
@@ -478,30 +475,36 @@ private fun TickerText(
|
|||||||
val velocityPxPerMs = with(density) { velocityDpPerSecond.dp.toPx() } / 1000f
|
val velocityPxPerMs = with(density) { velocityDpPerSecond.dp.toPx() } / 1000f
|
||||||
val totalScrollPx = textWidthPx + containerWidthPx
|
val totalScrollPx = textWidthPx + containerWidthPx
|
||||||
val scrollMs = (totalScrollPx / velocityPxPerMs).toInt()
|
val scrollMs = (totalScrollPx / velocityPxPerMs).toInt()
|
||||||
val initialDelayMs = 1500
|
|
||||||
val durationMs = initialDelayMs + scrollMs
|
|
||||||
|
|
||||||
val transition = rememberInfiniteTransition(label = "ticker")
|
val offset = remember { Animatable(0f) }
|
||||||
val offset by transition.animateFloat(
|
val alpha = remember { Animatable(0f) }
|
||||||
initialValue = 0f,
|
|
||||||
targetValue = 0f,
|
LaunchedEffect(textWidthPx, containerWidthPx) {
|
||||||
animationSpec = infiniteRepeatable(
|
offset.snapTo(0f)
|
||||||
animation = keyframes {
|
alpha.snapTo(0f)
|
||||||
durationMillis = durationMs
|
alpha.animateTo(1f, tween(300))
|
||||||
0f at 0 using LinearEasing
|
delay(1500L)
|
||||||
0f at initialDelayMs using LinearEasing
|
|
||||||
-totalScrollPx at durationMs using LinearEasing
|
while (true) {
|
||||||
},
|
offset.animateTo(
|
||||||
repeatMode = RepeatMode.Restart
|
-totalScrollPx,
|
||||||
),
|
tween(scrollMs, easing = LinearEasing)
|
||||||
label = "ticker"
|
)
|
||||||
)
|
offset.snapTo(0f)
|
||||||
|
alpha.snapTo(0f)
|
||||||
|
alpha.animateTo(1f, tween(300))
|
||||||
|
delay(500L)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.wrapContentWidth(align = Alignment.Start, unbounded = true)
|
.wrapContentWidth(align = Alignment.Start, unbounded = true)
|
||||||
.align(Alignment.CenterStart)
|
.align(Alignment.CenterStart)
|
||||||
.graphicsLayer { translationX = offset }
|
.graphicsLayer {
|
||||||
|
translationX = offset.value
|
||||||
|
this.alpha = alpha.value
|
||||||
|
}
|
||||||
) {
|
) {
|
||||||
if (strokeColor != null) {
|
if (strokeColor != null) {
|
||||||
Text(
|
Text(
|
||||||
|
|||||||
Reference in New Issue
Block a user