feat(ui): 为更改主题样式或颜色时添加动画

This commit is contained in:
Super12138 2025-02-05 16:33:22 +08:00
parent 121334498c
commit 086e0ce447

View file

@ -1,6 +1,11 @@
package cn.super12138.todo.ui.theme
import androidx.compose.animation.animateColorAsState
import androidx.compose.animation.core.AnimationSpec
import androidx.compose.animation.core.Spring
import androidx.compose.animation.core.spring
import androidx.compose.material3.ColorScheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Stable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.toArgb
@ -15,12 +20,14 @@ import com.kyant.m3color.scheme.SchemeRainbow
import com.kyant.m3color.scheme.SchemeTonalSpot
import com.kyant.m3color.scheme.SchemeVibrant
@Composable
@Stable
fun dynamicColorScheme(
keyColor: Color,
isDark: Boolean,
style: PaletteStyle = PaletteStyle.TonalSpot,
contrastLevel: Double = 0.0
contrastLevel: Double = 0.0,
animationSpec: AnimationSpec<Color> = spring()
): ColorScheme {
val hct = Hct.fromInt(keyColor.toArgb())
val scheme = when (style) {
@ -36,44 +43,50 @@ fun dynamicColorScheme(
}
return ColorScheme(
background = scheme.background.toColor(),
error = scheme.error.toColor(),
errorContainer = scheme.errorContainer.toColor(),
inverseOnSurface = scheme.inverseOnSurface.toColor(),
inversePrimary = scheme.inversePrimary.toColor(),
inverseSurface = scheme.inverseSurface.toColor(),
onBackground = scheme.onBackground.toColor(),
onError = scheme.onError.toColor(),
onErrorContainer = scheme.onErrorContainer.toColor(),
onPrimary = scheme.onPrimary.toColor(),
onPrimaryContainer = scheme.onPrimaryContainer.toColor(),
onSecondary = scheme.onSecondary.toColor(),
onSecondaryContainer = scheme.onSecondaryContainer.toColor(),
onSurface = scheme.onSurface.toColor(),
onSurfaceVariant = scheme.onSurfaceVariant.toColor(),
onTertiary = scheme.onTertiary.toColor(),
onTertiaryContainer = scheme.onTertiaryContainer.toColor(),
outline = scheme.outline.toColor(),
outlineVariant = scheme.outlineVariant.toColor(),
primary = scheme.primary.toColor(),
primaryContainer = scheme.primaryContainer.toColor(),
scrim = scheme.scrim.toColor(),
secondary = scheme.secondary.toColor(),
secondaryContainer = scheme.secondaryContainer.toColor(),
surface = scheme.surface.toColor(),
surfaceBright = scheme.surfaceBright.toColor(),
surfaceContainer = scheme.surfaceContainer.toColor(),
surfaceContainerLow = scheme.surfaceContainerLow.toColor(),
surfaceContainerLowest = scheme.surfaceContainerLowest.toColor(),
surfaceContainerHigh = scheme.surfaceContainerHigh.toColor(),
surfaceContainerHighest = scheme.surfaceContainerHighest.toColor(),
surfaceDim = scheme.surfaceDim.toColor(),
surfaceTint = scheme.surfaceTint.toColor(),
surfaceVariant = scheme.surfaceVariant.toColor(),
tertiary = scheme.tertiary.toColor(),
tertiaryContainer = scheme.tertiaryContainer.toColor(),
background = scheme.background.toColor().animate(animationSpec),
error = scheme.error.toColor().animate(animationSpec),
errorContainer = scheme.errorContainer.toColor().animate(animationSpec),
inverseOnSurface = scheme.inverseOnSurface.toColor().animate(animationSpec),
inversePrimary = scheme.inversePrimary.toColor().animate(animationSpec),
inverseSurface = scheme.inverseSurface.toColor().animate(animationSpec),
onBackground = scheme.onBackground.toColor().animate(animationSpec),
onError = scheme.onError.toColor().animate(animationSpec),
onErrorContainer = scheme.onErrorContainer.toColor().animate(animationSpec),
onPrimary = scheme.onPrimary.toColor().animate(animationSpec),
onPrimaryContainer = scheme.onPrimaryContainer.toColor().animate(animationSpec),
onSecondary = scheme.onSecondary.toColor().animate(animationSpec),
onSecondaryContainer = scheme.onSecondaryContainer.toColor().animate(animationSpec),
onSurface = scheme.onSurface.toColor().animate(animationSpec),
onSurfaceVariant = scheme.onSurfaceVariant.toColor().animate(animationSpec),
onTertiary = scheme.onTertiary.toColor().animate(animationSpec),
onTertiaryContainer = scheme.onTertiaryContainer.toColor().animate(animationSpec),
outline = scheme.outline.toColor().animate(animationSpec),
outlineVariant = scheme.outlineVariant.toColor().animate(animationSpec),
primary = scheme.primary.toColor().animate(animationSpec),
primaryContainer = scheme.primaryContainer.toColor().animate(animationSpec),
scrim = scheme.scrim.toColor().animate(animationSpec),
secondary = scheme.secondary.toColor().animate(animationSpec),
secondaryContainer = scheme.secondaryContainer.toColor().animate(animationSpec),
surface = scheme.surface.toColor().animate(animationSpec),
surfaceBright = scheme.surfaceBright.toColor().animate(animationSpec),
surfaceContainer = scheme.surfaceContainer.toColor().animate(animationSpec),
surfaceContainerLow = scheme.surfaceContainerLow.toColor().animate(animationSpec),
surfaceContainerLowest = scheme.surfaceContainerLowest.toColor().animate(animationSpec),
surfaceContainerHigh = scheme.surfaceContainerHigh.toColor().animate(animationSpec),
surfaceContainerHighest = scheme.surfaceContainerHighest.toColor().animate(animationSpec),
surfaceDim = scheme.surfaceDim.toColor().animate(animationSpec),
surfaceTint = scheme.surfaceTint.toColor().animate(animationSpec),
surfaceVariant = scheme.surfaceVariant.toColor().animate(animationSpec),
tertiary = scheme.tertiary.toColor().animate(animationSpec),
tertiaryContainer = scheme.tertiaryContainer.toColor().animate(animationSpec),
)
}
@Suppress("NOTHING_TO_INLINE")
private inline fun Int.toColor(): Color = Color(this)
private inline fun Int.toColor(): Color = Color(this)
// https://github.com/jordond/MaterialKolor/blob/main/material-kolor/src/commonMain/kotlin/com/materialkolor/DynamicMaterialTheme.kt
@Composable
private fun Color.animate(animationSpec: AnimationSpec<Color> = spring()): Color {
return animateColorAsState(this, animationSpec).value
}