Skip to content

Commit

Permalink
animate theme change
Browse files Browse the repository at this point in the history
  • Loading branch information
DatL4g committed Apr 30, 2024
1 parent 2ab276a commit 24e3b42
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 47 deletions.
7 changes: 5 additions & 2 deletions composeApp/src/commonMain/kotlin/dev/datlag/aniflow/App.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.font.FontWeight
import dev.chrisbanes.haze.HazeState
import dev.datlag.aniflow.common.toComposeColor
import dev.datlag.aniflow.other.StateSaver
import dev.datlag.aniflow.settings.Settings
import dev.datlag.aniflow.settings.model.AppSettings
import dev.datlag.aniflow.ui.theme.Colors
Expand Down Expand Up @@ -54,11 +55,13 @@ internal fun App(
appSettings.color
}.collectAsStateWithLifecycle(null)
val seedColor = remember(savedColor) { savedColor?.toComposeColor() }
val allLoading by StateSaver.Home.isAllLoading.collectAsStateWithLifecycle(true)

DynamicMaterialTheme(
seedColor = seedColor
seedColor = seedColor,
animate = !allLoading
) {
CommonSchemeTheme {
CommonSchemeTheme(animate = !allLoading) {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ fun Component.onRender(content: @Composable () -> Unit) {
@Composable
fun Component.onRenderWithScheme(key: Any?, content: @Composable (SchemeTheme.Updater?) -> Unit) {
onRender {
SchemeTheme(key, content)
SchemeTheme(key = key, content = content)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@ import dev.datlag.aniflow.LocalDarkMode
@Composable
fun DynamicMaterialTheme(
seedColor: Color?,
animate: Boolean = false,
animationSpec: AnimationSpec<Color> = spring(stiffness = Spring.StiffnessLow),
content: @Composable () -> Unit
) {

val dynamicColorScheme = if (seedColor != null) {
rememberDynamicColorScheme(
seedColor = seedColor,
Expand All @@ -29,47 +30,51 @@ fun DynamicMaterialTheme(
} else {
MaterialTheme.colorScheme
}
val colorScheme = dynamicColorScheme.copy(
primary = dynamicColorScheme.primary,
primaryContainer = dynamicColorScheme.primaryContainer,
secondary = dynamicColorScheme.secondary,
secondaryContainer = dynamicColorScheme.secondaryContainer,
tertiary = dynamicColorScheme.tertiary,
tertiaryContainer = dynamicColorScheme.tertiaryContainer,
background = dynamicColorScheme.background,
surface = dynamicColorScheme.surface,
surfaceTint = dynamicColorScheme.surfaceTint,
surfaceBright = dynamicColorScheme.surfaceBright,
surfaceDim = dynamicColorScheme.surfaceDim,
surfaceContainer = dynamicColorScheme.surfaceContainer,
surfaceContainerHigh = dynamicColorScheme.surfaceContainerHigh,
surfaceContainerHighest = dynamicColorScheme.surfaceContainerHighest,
surfaceContainerLow = dynamicColorScheme.surfaceContainerLow,
surfaceContainerLowest = dynamicColorScheme.surfaceContainerLowest,
surfaceVariant = dynamicColorScheme.surfaceVariant,
error = dynamicColorScheme.error,
errorContainer = dynamicColorScheme.errorContainer,
onPrimary = dynamicColorScheme.onPrimary,
onPrimaryContainer = dynamicColorScheme.onPrimaryContainer,
onSecondary = dynamicColorScheme.onSecondary,
onSecondaryContainer = dynamicColorScheme.onSecondaryContainer,
onTertiary = dynamicColorScheme.onTertiary,
onTertiaryContainer = dynamicColorScheme.onTertiaryContainer,
onBackground = dynamicColorScheme.onBackground,
onSurface = dynamicColorScheme.onSurface,
onSurfaceVariant = dynamicColorScheme.onSurfaceVariant,
onError = dynamicColorScheme.onError,
onErrorContainer = dynamicColorScheme.onErrorContainer,
inversePrimary = dynamicColorScheme.inversePrimary,
inverseSurface = dynamicColorScheme.inverseSurface,
inverseOnSurface = dynamicColorScheme.inverseOnSurface,
outline = dynamicColorScheme.outline,
outlineVariant = dynamicColorScheme.outlineVariant,
scrim = dynamicColorScheme.scrim,
)
val animatedColorScheme = if (!animate) {
dynamicColorScheme
} else {
dynamicColorScheme.copy(
primary = dynamicColorScheme.primary.animate(animationSpec),
primaryContainer = dynamicColorScheme.primaryContainer.animate(animationSpec),
secondary = dynamicColorScheme.secondary.animate(animationSpec),
secondaryContainer = dynamicColorScheme.secondaryContainer.animate(animationSpec),
tertiary = dynamicColorScheme.tertiary.animate(animationSpec),
tertiaryContainer = dynamicColorScheme.tertiaryContainer.animate(animationSpec),
background = dynamicColorScheme.background.animate(animationSpec),
surface = dynamicColorScheme.surface.animate(animationSpec),
surfaceTint = dynamicColorScheme.surfaceTint.animate(animationSpec),
surfaceBright = dynamicColorScheme.surfaceBright.animate(animationSpec),
surfaceDim = dynamicColorScheme.surfaceDim.animate(animationSpec),
surfaceContainer = dynamicColorScheme.surfaceContainer.animate(animationSpec),
surfaceContainerHigh = dynamicColorScheme.surfaceContainerHigh.animate(animationSpec),
surfaceContainerHighest = dynamicColorScheme.surfaceContainerHighest.animate(animationSpec),
surfaceContainerLow = dynamicColorScheme.surfaceContainerLow.animate(animationSpec),
surfaceContainerLowest = dynamicColorScheme.surfaceContainerLowest.animate(animationSpec),
surfaceVariant = dynamicColorScheme.surfaceVariant.animate(animationSpec),
error = dynamicColorScheme.error.animate(animationSpec),
errorContainer = dynamicColorScheme.errorContainer.animate(animationSpec),
onPrimary = dynamicColorScheme.onPrimary.animate(animationSpec),
onPrimaryContainer = dynamicColorScheme.onPrimaryContainer.animate(animationSpec),
onSecondary = dynamicColorScheme.onSecondary.animate(animationSpec),
onSecondaryContainer = dynamicColorScheme.onSecondaryContainer.animate(animationSpec),
onTertiary = dynamicColorScheme.onTertiary.animate(animationSpec),
onTertiaryContainer = dynamicColorScheme.onTertiaryContainer.animate(animationSpec),
onBackground = dynamicColorScheme.onBackground.animate(animationSpec),
onSurface = dynamicColorScheme.onSurface.animate(animationSpec),
onSurfaceVariant = dynamicColorScheme.onSurfaceVariant.animate(animationSpec),
onError = dynamicColorScheme.onError.animate(animationSpec),
onErrorContainer = dynamicColorScheme.onErrorContainer.animate(animationSpec),
inversePrimary = dynamicColorScheme.inversePrimary.animate(animationSpec),
inverseSurface = dynamicColorScheme.inverseSurface.animate(animationSpec),
inverseOnSurface = dynamicColorScheme.inverseOnSurface.animate(animationSpec),
outline = dynamicColorScheme.outline.animate(animationSpec),
outlineVariant = dynamicColorScheme.outlineVariant.animate(animationSpec),
scrim = dynamicColorScheme.scrim.animate(animationSpec),
)
}

MaterialTheme(
colorScheme = colorScheme
colorScheme = animatedColorScheme
) {
content()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,25 +165,30 @@ fun rememberSchemeThemeDominantColorState(
}

@Composable
fun SchemeTheme(key: Any?, content: @Composable (SchemeTheme.Updater?) -> Unit) {
fun SchemeTheme(
key: Any?,
animate: Boolean = false,
content: @Composable (SchemeTheme.Updater?) -> Unit
) {
val state = rememberSchemeThemeDominantColorState(key)
val scope = rememberCoroutineScope()
val updater = remember(key, scope) {
key?.let { SchemeTheme.Updater.Default(it, scope) }
} ?: SchemeTheme.create(key)

DynamicMaterialTheme(
seedColor = state?.color
seedColor = state?.color,
animate = animate
) {
content(updater)
}
}

@Composable
fun CommonSchemeTheme(content: @Composable (SchemeTheme.Updater?) -> Unit) {
fun CommonSchemeTheme(animate: Boolean = false, content: @Composable (SchemeTheme.Updater?) -> Unit) {
val key by SchemeTheme.commonSchemeKey.collectAsStateWithLifecycle()

SchemeTheme(key, content)
SchemeTheme(key, animate, content)
}

private fun Color.contrastAgainst(background: Color): Float {
Expand Down

0 comments on commit 24e3b42

Please sign in to comment.