1package com.peachpasswords.ui.components23import androidx.compose.animation.core.animateFloatAsState4import androidx.compose.animation.core.tween5import androidx.compose.material3.Text6import androidx.compose.runtime.Composable7import androidx.compose.runtime.LaunchedEffect8import androidx.compose.runtime.getValue9import androidx.compose.runtime.mutableStateOf10import androidx.compose.runtime.remember11import androidx.compose.runtime.setValue12import androidx.compose.ui.Modifier13import androidx.compose.ui.graphics.graphicsLayer14import androidx.compose.ui.layout.Layout15import androidx.compose.ui.platform.LocalDensity16import androidx.compose.ui.text.TextStyle17import com.peachpasswords.ui.theme.LocalReduceMotion18import com.peachpasswords.ui.theme.PeachMotion19import kotlinx.coroutines.delay20212223242526@Composable27fun CharEnterText(28 text: String,29 style: TextStyle,30 modifier: Modifier = Modifier,31) {32 val reduceMotion = LocalReduceMotion.current33 var visible by remember(text) { mutableStateOf(reduceMotion) }34 LaunchedEffect(text) {35 if (!reduceMotion) { delay(50); visible = true }36 }37 val density = LocalDensity.current38 val riseStartPx = with(density) { (style.fontSize.toPx() * 0.22f) }3940 Layout(41 modifier = modifier,42 content = {43 text.forEachIndexed { index, char ->44 val alpha by animateFloatAsState(45 targetValue = if (visible) 1f else 0f,46 animationSpec = tween(PeachMotion.CharDuration, index * PeachMotion.CharDelay, PeachMotion.Spring),47 label = "char-alpha",48 )49 val rise by animateFloatAsState(50 targetValue = if (visible) 0f else riseStartPx,51 animationSpec = tween(PeachMotion.CharDuration, index * PeachMotion.CharDelay, PeachMotion.Spring),52 label = "char-rise",53 )54 Text(55 text = char.toString(),56 style = style,57 modifier = Modifier.charState(alpha, rise),58 )59 }60 },61 ) { measurables, constraints ->62 val placeables = measurables.map { it.measure(constraints) }63 val width = placeables.sumOf { it.width }64 val height = placeables.maxOfOrNull { it.height } ?: 065 layout(width, height) {66 var x = 067 placeables.forEach { p ->68 p.placeRelativeWithLayer(x, 0)69 x += p.width70 }71 }72 }73}7475private fun Modifier.charState(alpha: Float, riseY: Float): Modifier =76 this.graphicsLayer { this.alpha = alpha; this.translationY = riseY }