Skip to content

Commit

Permalink
SplashScreen - janky frame
Browse files Browse the repository at this point in the history
  • Loading branch information
ksharma-xyz committed Nov 9, 2024
1 parent 67ee4a9 commit d1cedd7
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 22 deletions.
12 changes: 11 additions & 1 deletion app/src/main/kotlin/xyz/ksharma/krail/navigation/KrailNavHost.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@ import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.navigation.NavOptions
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import kotlinx.serialization.Serializable
import xyz.ksharma.krail.design.system.LocalThemeColor
import xyz.ksharma.krail.design.system.LocalThemeContentColor
import xyz.ksharma.krail.design.system.theme.KrailTheme
import xyz.ksharma.krail.design.system.theme.getForegroundColor
import xyz.ksharma.krail.design.system.unspecifiedColor
import xyz.ksharma.krail.splash.SplashScreen
Expand Down Expand Up @@ -61,11 +63,19 @@ fun KrailNavHost(modifier: Modifier = Modifier) {

composable<SplashScreen> {
val viewModel = hiltViewModel<SplashViewModel>()
val mode = viewModel.getThemeTransportMode()
val isLoading by viewModel.isLoading.collectAsStateWithLifecycle()
val mode by viewModel.uiState.collectAsStateWithLifecycle()

productClass = mode?.productClass
themeColorHexCode.value = mode?.colorCode ?: unspecifiedColor

SplashScreen(
logoColor = if (productClass != null && themeColorHexCode.value != unspecifiedColor) {
themeColorHexCode.value.hexToComposeColor()
} else {
KrailTheme.colors.onSurface
},
backgroundColor = KrailTheme.colors.surface,
onSplashComplete = {
navController.navigate(
route = if (productClass != null) {
Expand Down
50 changes: 33 additions & 17 deletions app/src/main/kotlin/xyz/ksharma/krail/splash/SplashScreen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import androidx.compose.animation.core.infiniteRepeatable
import androidx.compose.animation.core.keyframes
import androidx.compose.animation.core.rememberInfiniteTransition
import androidx.compose.foundation.background
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
Expand All @@ -19,6 +18,7 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberUpdatedState
Expand All @@ -38,18 +38,21 @@ import androidx.compose.ui.unit.sp
import kotlinx.coroutines.delay
import xyz.ksharma.krail.design.system.components.Text
import xyz.ksharma.krail.design.system.theme.KrailTheme
import kotlin.time.Duration
import kotlin.time.Duration.Companion.milliseconds

@Composable
fun SplashScreen(onSplashComplete: () -> Unit, modifier: Modifier = Modifier) {
fun SplashScreen(
logoColor: Color?,
backgroundColor: Color?,
onSplashComplete: () -> Unit,
modifier: Modifier = Modifier,
) {
Box(
modifier = modifier
.fillMaxSize()
.background(color = KrailTheme.colors.surface),
.background(color = backgroundColor ?: KrailTheme.colors.surface),
contentAlignment = Alignment.Center,
) {
AnimatedKrailLogo()
AnimatedKrailLogo(logoColor = logoColor ?: KrailTheme.colors.onSurface)

val splashComplete by rememberUpdatedState(onSplashComplete)
LaunchedEffect(key1 = Unit) {
Expand All @@ -60,7 +63,10 @@ fun SplashScreen(onSplashComplete: () -> Unit, modifier: Modifier = Modifier) {
}

@Composable
private fun AnimatedKrailLogo(modifier: Modifier = Modifier) {
private fun AnimatedKrailLogo(
logoColor: Color,
modifier: Modifier = Modifier,
) {
var animationStarted by remember { mutableStateOf(false) }

LaunchedEffect(key1 = Unit) {
Expand All @@ -72,27 +78,32 @@ private fun AnimatedKrailLogo(modifier: Modifier = Modifier) {
letter = "K",
animationStarted = animationStarted,
fontSize = 80.sp,
delayMillis = 0.milliseconds,
delayMillis = 0,
logoColor = logoColor,
modifier = Modifier.alignByBaseline(),
)
AnimatedLetter(
letter = "R",
animationStarted = animationStarted,
logoColor = logoColor,
modifier = Modifier.alignByBaseline(),
)
AnimatedLetter(
letter = "A",
animationStarted = animationStarted,
logoColor = logoColor,
modifier = Modifier.alignByBaseline(),
)
AnimatedLetter(
letter = "I",
animationStarted = animationStarted,
logoColor = logoColor,
modifier = Modifier.alignByBaseline(),
)
AnimatedLetter(
letter = "L",
animationStarted = animationStarted,
logoColor = logoColor,
modifier = Modifier.alignByBaseline(),
)
}
Expand All @@ -103,6 +114,7 @@ private fun AnimatedKrailLogo(modifier: Modifier = Modifier) {
fontWeight = FontWeight.Normal,
),
textAlign = TextAlign.Center,
color = logoColor,
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp, vertical = 0.dp),
Expand All @@ -114,9 +126,10 @@ private fun AnimatedKrailLogo(modifier: Modifier = Modifier) {
private fun AnimatedLetter(
letter: String,
animationStarted: Boolean,
logoColor: Color,
modifier: Modifier = Modifier,
fontSize: TextUnit = TextUnit(65F, TextUnitType.Sp),
delayMillis: Duration = 100.milliseconds,
delayMillis: Int = 100,
) {
val infiniteTransition = rememberInfiniteTransition(label = "animeAnimation")

Expand All @@ -134,23 +147,22 @@ private fun AnimatedLetter(
1.0f at 1100 using LinearEasing // Keep at normal scale
},
repeatMode = RepeatMode.Reverse,
initialStartOffset = StartOffset(offsetMillis = delayMillis.inWholeMilliseconds.toInt()),
initialStartOffset = StartOffset(offsetMillis = delayMillis),
),
label = "animeAnimation",
)

val letterScale = if (animationStarted) scale else 1f
val letterScale by remember(scale) {
mutableFloatStateOf(if (animationStarted) scale else 1f)
}

Text(
text = letter,
color = if (isSystemInDarkTheme()) Color(0xFFFFFF33) else Color(0xFFFF69B4),
color = logoColor,
style = KrailTheme.typography.displayLarge.copy(
fontSize = fontSize,
letterSpacing = 4.sp,
fontWeight = FontWeight.ExtraBold,
/*drawStyle = Stroke(
width = 8f, // Adjust stroke width for desired thickness
),*/
),
modifier = modifier
.graphicsLayer {
Expand All @@ -167,7 +179,7 @@ private fun AnimatedLetter(
private fun PreviewLogo() {
KrailTheme {
Column(modifier = Modifier.background(color = KrailTheme.colors.surface)) {
AnimatedKrailLogo()
AnimatedKrailLogo(logoColor = Color(0xFFF6891F))
}
}
}
Expand All @@ -176,6 +188,10 @@ private fun PreviewLogo() {
@Composable
private fun PreviewSplashScreen() {
KrailTheme {
SplashScreen(onSplashComplete = {})
SplashScreen(
onSplashComplete = {},
logoColor = KrailTheme.colors.onSurface,
backgroundColor = Color(0xFF009B77),
)
}
}
27 changes: 23 additions & 4 deletions app/src/main/kotlin/xyz/ksharma/krail/splash/SplashViewModel.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
package xyz.ksharma.krail.splash

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
import xyz.ksharma.krail.sandook.Sandook
import xyz.ksharma.krail.sandook.di.SandookFactory
import xyz.ksharma.krail.trip.planner.ui.state.TransportMode
Expand All @@ -14,9 +22,20 @@ class SplashViewModel @Inject constructor(

private val sandook: Sandook = sandookFactory.create(SandookFactory.SandookKey.THEME)

fun getThemeTransportMode(): TransportMode? {
val productClass = sandook.getInt("selectedMode")
val mode = TransportMode.toTransportModeType(productClass)
return mode
private val _uiState: MutableStateFlow<TransportMode?> = MutableStateFlow(null)
val uiState: MutableStateFlow<TransportMode?> = _uiState

private val _isLoading: MutableStateFlow<Boolean> = MutableStateFlow(false)
val isLoading: StateFlow<Boolean> = _isLoading
.onStart {
getThemeTransportMode()
}.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), true)

private fun getThemeTransportMode() {
viewModelScope.launch(Dispatchers.IO) {
val productClass = sandook.getInt("selectedMode")
val mode = TransportMode.toTransportModeType(productClass)
_uiState.value = mode
}
}
}

0 comments on commit d1cedd7

Please sign in to comment.