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 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.material3.ColorScheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Stable import androidx.compose.runtime.Stable
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.toArgb 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.SchemeTonalSpot
import com.kyant.m3color.scheme.SchemeVibrant import com.kyant.m3color.scheme.SchemeVibrant
@Composable
@Stable @Stable
fun dynamicColorScheme( fun dynamicColorScheme(
keyColor: Color, keyColor: Color,
isDark: Boolean, isDark: Boolean,
style: PaletteStyle = PaletteStyle.TonalSpot, style: PaletteStyle = PaletteStyle.TonalSpot,
contrastLevel: Double = 0.0 contrastLevel: Double = 0.0,
animationSpec: AnimationSpec<Color> = spring()
): ColorScheme { ): ColorScheme {
val hct = Hct.fromInt(keyColor.toArgb()) val hct = Hct.fromInt(keyColor.toArgb())
val scheme = when (style) { val scheme = when (style) {
@ -36,44 +43,50 @@ fun dynamicColorScheme(
} }
return ColorScheme( return ColorScheme(
background = scheme.background.toColor(), background = scheme.background.toColor().animate(animationSpec),
error = scheme.error.toColor(), error = scheme.error.toColor().animate(animationSpec),
errorContainer = scheme.errorContainer.toColor(), errorContainer = scheme.errorContainer.toColor().animate(animationSpec),
inverseOnSurface = scheme.inverseOnSurface.toColor(), inverseOnSurface = scheme.inverseOnSurface.toColor().animate(animationSpec),
inversePrimary = scheme.inversePrimary.toColor(), inversePrimary = scheme.inversePrimary.toColor().animate(animationSpec),
inverseSurface = scheme.inverseSurface.toColor(), inverseSurface = scheme.inverseSurface.toColor().animate(animationSpec),
onBackground = scheme.onBackground.toColor(), onBackground = scheme.onBackground.toColor().animate(animationSpec),
onError = scheme.onError.toColor(), onError = scheme.onError.toColor().animate(animationSpec),
onErrorContainer = scheme.onErrorContainer.toColor(), onErrorContainer = scheme.onErrorContainer.toColor().animate(animationSpec),
onPrimary = scheme.onPrimary.toColor(), onPrimary = scheme.onPrimary.toColor().animate(animationSpec),
onPrimaryContainer = scheme.onPrimaryContainer.toColor(), onPrimaryContainer = scheme.onPrimaryContainer.toColor().animate(animationSpec),
onSecondary = scheme.onSecondary.toColor(), onSecondary = scheme.onSecondary.toColor().animate(animationSpec),
onSecondaryContainer = scheme.onSecondaryContainer.toColor(), onSecondaryContainer = scheme.onSecondaryContainer.toColor().animate(animationSpec),
onSurface = scheme.onSurface.toColor(), onSurface = scheme.onSurface.toColor().animate(animationSpec),
onSurfaceVariant = scheme.onSurfaceVariant.toColor(), onSurfaceVariant = scheme.onSurfaceVariant.toColor().animate(animationSpec),
onTertiary = scheme.onTertiary.toColor(), onTertiary = scheme.onTertiary.toColor().animate(animationSpec),
onTertiaryContainer = scheme.onTertiaryContainer.toColor(), onTertiaryContainer = scheme.onTertiaryContainer.toColor().animate(animationSpec),
outline = scheme.outline.toColor(), outline = scheme.outline.toColor().animate(animationSpec),
outlineVariant = scheme.outlineVariant.toColor(), outlineVariant = scheme.outlineVariant.toColor().animate(animationSpec),
primary = scheme.primary.toColor(), primary = scheme.primary.toColor().animate(animationSpec),
primaryContainer = scheme.primaryContainer.toColor(), primaryContainer = scheme.primaryContainer.toColor().animate(animationSpec),
scrim = scheme.scrim.toColor(), scrim = scheme.scrim.toColor().animate(animationSpec),
secondary = scheme.secondary.toColor(), secondary = scheme.secondary.toColor().animate(animationSpec),
secondaryContainer = scheme.secondaryContainer.toColor(), secondaryContainer = scheme.secondaryContainer.toColor().animate(animationSpec),
surface = scheme.surface.toColor(), surface = scheme.surface.toColor().animate(animationSpec),
surfaceBright = scheme.surfaceBright.toColor(), surfaceBright = scheme.surfaceBright.toColor().animate(animationSpec),
surfaceContainer = scheme.surfaceContainer.toColor(), surfaceContainer = scheme.surfaceContainer.toColor().animate(animationSpec),
surfaceContainerLow = scheme.surfaceContainerLow.toColor(), surfaceContainerLow = scheme.surfaceContainerLow.toColor().animate(animationSpec),
surfaceContainerLowest = scheme.surfaceContainerLowest.toColor(), surfaceContainerLowest = scheme.surfaceContainerLowest.toColor().animate(animationSpec),
surfaceContainerHigh = scheme.surfaceContainerHigh.toColor(), surfaceContainerHigh = scheme.surfaceContainerHigh.toColor().animate(animationSpec),
surfaceContainerHighest = scheme.surfaceContainerHighest.toColor(), surfaceContainerHighest = scheme.surfaceContainerHighest.toColor().animate(animationSpec),
surfaceDim = scheme.surfaceDim.toColor(), surfaceDim = scheme.surfaceDim.toColor().animate(animationSpec),
surfaceTint = scheme.surfaceTint.toColor(), surfaceTint = scheme.surfaceTint.toColor().animate(animationSpec),
surfaceVariant = scheme.surfaceVariant.toColor(), surfaceVariant = scheme.surfaceVariant.toColor().animate(animationSpec),
tertiary = scheme.tertiary.toColor(), tertiary = scheme.tertiary.toColor().animate(animationSpec),
tertiaryContainer = scheme.tertiaryContainer.toColor(), tertiaryContainer = scheme.tertiaryContainer.toColor().animate(animationSpec),
) )
} }
@Suppress("NOTHING_TO_INLINE") @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
}