From eabdda867d6607eeaab2234b5f4d0a0a45df873a Mon Sep 17 00:00:00 2001 From: Tangem Date: Mon, 16 Mar 2026 13:59:27 +0300 Subject: [PATCH] Updated on 2026-08-14 --- .../MovingColorfulBlubsBackground.kt | 26 +++-- .../NorthernLightsBackground.kt | 104 ++++++------------ .../presentation/wallet/ui/WalletScreen2.kt | 5 +- 3 files changed, 50 insertions(+), 85 deletions(-) diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/background/northernlights/MovingColorfulBlubsBackground.kt b/core/ui/src/main/java/com/tangem/core/ui/components/background/northernlights/MovingColorfulBlubsBackground.kt index f4e9988a2b..3d197fbc4a 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/components/background/northernlights/MovingColorfulBlubsBackground.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/components/background/northernlights/MovingColorfulBlubsBackground.kt @@ -16,16 +16,18 @@ import androidx.compose.ui.geometry.Rect import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Paint import androidx.compose.ui.graphics.drawscope.drawIntoCanvas +import com.tangem.core.ui.res.LocalIsInDarkTheme @Suppress("LongMethod") @Composable internal fun MovingColorfulBlubsBackground(modifier: Modifier = Modifier) { val transition = rememberInfiniteTransition(label = "FluidMeshGradient") + val isDark = LocalIsInDarkTheme.current - // ── Circle 1 (left) ────────────────────────────────────────────────────── + // ── Circle 1 (left) — matches dc1 / lc1 from shader version ───────────── val color1 by transition.animateColor( - initialValue = Color(0xFF3355EE), - targetValue = Color(0xFF5577FF), + initialValue = if (isDark) Color(0xFF0D0D3A) else Color(0xFFCCB8EE), + targetValue = if (isDark) Color(0xFF1C1C6E) else Color(0xFFBBA0E8), animationSpec = infiniteRepeatable( animation = tween(4_000, easing = FastOutSlowInEasing), repeatMode = RepeatMode.Reverse, @@ -51,10 +53,10 @@ internal fun MovingColorfulBlubsBackground(modifier: Modifier = Modifier) { label = "y1", ) - // ── Circle 2 (right) ───────────────────────────────────────────────────── + // ── Circle 2 (right) — matches dc2 / lc2 from shader version ──────────── val color2 by transition.animateColor( - initialValue = Color(0xFF7733CC), - targetValue = Color(0xFF4455EE), + initialValue = if (isDark) Color(0xFF0A1238) else Color(0xFFB8C8F0), + targetValue = if (isDark) Color(0xFF112266) else Color(0xFF9AAEE8), animationSpec = infiniteRepeatable( animation = tween(5_000, easing = FastOutSlowInEasing), repeatMode = RepeatMode.Reverse, @@ -82,10 +84,10 @@ internal fun MovingColorfulBlubsBackground(modifier: Modifier = Modifier) { label = "y2", ) - // ── Oval (center) ──────────────────────────────────────────────────────── + // ── Oval (center) — matches dc4 / lc4 from shader version ─────────────── val ovalColor by transition.animateColor( - initialValue = Color(0xFF5533CC), - targetValue = Color(0xFF8844EE), + initialValue = if (isDark) Color(0xFF081A30) else Color(0xFFB8C4EE), + targetValue = if (isDark) Color(0xFF113355) else Color(0xFFA8B4E8), animationSpec = infiniteRepeatable( animation = tween(7_000, easing = FastOutSlowInEasing), repeatMode = RepeatMode.Reverse, @@ -93,10 +95,10 @@ internal fun MovingColorfulBlubsBackground(modifier: Modifier = Modifier) { ), label = "ovalColor", ) - // ── Circle 3 (center) ──────────────────────────────────────────────────── + // ── Circle 3 (center) — matches dc3 / lc3 from shader version ─────────── val color3 by transition.animateColor( - initialValue = Color(0xFF9933BB), - targetValue = Color(0xFFBB44DD), + initialValue = if (isDark) Color(0xFF110A38) else Color(0xFFDDC8F5), + targetValue = if (isDark) Color(0xFF2A1666) else Color(0xFFCCB0EE), animationSpec = infiniteRepeatable( animation = tween(6_000, easing = FastOutSlowInEasing), repeatMode = RepeatMode.Reverse, diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/background/northernlights/NorthernLightsBackground.kt b/core/ui/src/main/java/com/tangem/core/ui/components/background/northernlights/NorthernLightsBackground.kt index 27b3583edc..7d8a8aa875 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/components/background/northernlights/NorthernLightsBackground.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/components/background/northernlights/NorthernLightsBackground.kt @@ -15,6 +15,7 @@ import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import com.tangem.core.ui.components.background.shaderBackground +import com.tangem.core.ui.res.LocalIsInDarkTheme import com.tangem.core.ui.res.LocalPowerSavingState import com.tangem.core.ui.shader.NorthernLightsMeshGradientShader @@ -36,99 +37,58 @@ fun NorthernLightsBackground( } } -@Suppress("LongMethod") +@Suppress("LongMethod", "NamedArguments") @Composable private fun NorthernLightsBackgroundWithShader(containerColor: Color, modifier: Modifier = Modifier) { val transition = rememberInfiniteTransition(label = "FluidMeshGradientV2") + val isDark = LocalIsInDarkTheme.current - // Each track cycles through 4 states (matching the screenshot frames): - // deep/dark → saturated+bright → light/pastel → vibrant/vivid → back - // 16 s total per track, staggered so no two tracks peak simultaneously. - - // ── Color 1 – indigo → bright blue → lavender → hot violet ────────────── - val color1 by transition.animateColor( - initialValue = Color(0xFF2A1480), - targetValue = Color(0xFF2A1480), + @Composable + fun anim(a: Color, b: Color, c: Color, d: Color, offset: Int = 0) = transition.animateColor( + initialValue = a, + targetValue = a, animationSpec = infiniteRepeatable( animation = keyframes { - durationMillis = 16_000 - Color(0xFF2A1480) at 0 using FastOutSlowInEasing - Color(0xFF4477EE) at 4_000 using FastOutSlowInEasing - Color(0xFFBBAAEE) at 8_000 using FastOutSlowInEasing - Color(0xFF8833EE) at 12_000 using FastOutSlowInEasing + durationMillis = 40_000 + a at 0 using FastOutSlowInEasing + b at 10_000 using FastOutSlowInEasing + c at 20_000 using FastOutSlowInEasing + d at 30_000 using FastOutSlowInEasing }, repeatMode = RepeatMode.Restart, + initialStartOffset = StartOffset(offset), ), - label = "color1", + label = "c$offset", ) - // ── Color 2 – dark blue → cyan-blue → sky → teal ───────────────────────── - val color2 by transition.animateColor( - initialValue = Color(0xFF1444AA), - targetValue = Color(0xFF1444AA), - animationSpec = infiniteRepeatable( - animation = keyframes { - durationMillis = 16_000 - Color(0xFF1444AA) at 0 using FastOutSlowInEasing - Color(0xFF22AADD) at 4_000 using FastOutSlowInEasing - Color(0xFF99BBDD) at 8_000 using FastOutSlowInEasing - Color(0xFF44DDCC) at 12_000 using FastOutSlowInEasing - }, - repeatMode = RepeatMode.Restart, - initialStartOffset = StartOffset(4_000), - ), - label = "color2", - ) + val dc1 by anim(Color(0xFF0D0D3A), Color(0xFF141455), Color(0xFF1C1C6E), Color(0xFF111148), 0) + val dc2 by anim(Color(0xFF0A1238), Color(0xFF0D1D55), Color(0xFF112266), Color(0xFF0E1A4A), 10_000) + val dc3 by anim(Color(0xFF110A38), Color(0xFF1C1050), Color(0xFF2A1666), Color(0xFF180E48), 20_000) + val dc4 by anim(Color(0xFF081A30), Color(0xFF0D2844), Color(0xFF113355), Color(0xFF0D2240), 5_000) - // ── Color 3 – dark purple → medium purple → rose pink → magenta ────────── - val color3 by transition.animateColor( - initialValue = Color(0xFF4422BB), - targetValue = Color(0xFF4422BB), - animationSpec = infiniteRepeatable( - animation = keyframes { - durationMillis = 16_000 - Color(0xFF4422BB) at 0 using FastOutSlowInEasing - Color(0xFF7733CC) at 4_000 using FastOutSlowInEasing - Color(0xFFDD88BB) at 8_000 using FastOutSlowInEasing - Color(0xFFEE44AA) at 12_000 using FastOutSlowInEasing - }, - repeatMode = RepeatMode.Restart, - initialStartOffset = StartOffset(8_000), - ), - label = "color3", - ) + val lc1 by anim(Color(0xFFCCB8EE), Color(0xFFBBA0E8), Color(0xFFCCB0F0), Color(0xFFC4AAEC), 0) + val lc2 by anim(Color(0xFFB8C8F0), Color(0xFF9AAEE8), Color(0xFFAABEF0), Color(0xFFA0B8EE), 10_000) + val lc3 by anim(Color(0xFFDDC8F5), Color(0xFFCCB0EE), Color(0xFFD8BEF5), Color(0xFFD0B8F2), 20_000) + val lc4 by anim(Color(0xFFB8C4EE), Color(0xFFA8B4E8), Color(0xFFB4C0EE), Color(0xFFAABCEC), 5_000) - // ── Color 4 – dark violet → medium violet → light pink → hot pink ──────── - val color4 by transition.animateColor( - initialValue = Color(0xFF331199), - targetValue = Color(0xFF331199), - animationSpec = infiniteRepeatable( - animation = keyframes { - durationMillis = 16_000 - Color(0xFF331199) at 0 using FastOutSlowInEasing - Color(0xFF6644CC) at 4_000 using FastOutSlowInEasing - Color(0xFFCC77DD) at 8_000 using FastOutSlowInEasing - Color(0xFFFF66CC) at 12_000 using FastOutSlowInEasing - }, - repeatMode = RepeatMode.Restart, - initialStartOffset = StartOffset(2_000), - ), - label = "color4", - ) + val color1 = if (isDark) dc1 else lc1 + val color2 = if (isDark) dc2 else lc2 + val color3 = if (isDark) dc3 else lc3 + val color4 = if (isDark) dc4 else lc4 // Keep a stable shader instance so the RuntimeShader is never recreated. // Colors are pushed each recomposition via updateColors(). val shader = remember { NorthernLightsMeshGradientShader( colors = arrayOf( - Color(0xFF2A1480), - Color(0xFF1444AA), - Color(0xFF4422BB), - Color(0xFF331199), + color1, + color2, + color3, + color4, containerColor, ), - speed = 0.5f, - scale = 4f, + speed = 0.07f, + scale = 1.8f, ) } val colorsArray = remember { Array(5) { Color.Unspecified } } diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/WalletScreen2.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/WalletScreen2.kt index 7ca5c1dbf1..5053fbfbda 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/WalletScreen2.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/WalletScreen2.kt @@ -31,6 +31,7 @@ import androidx.compose.ui.focus.FocusState import androidx.compose.ui.focus.onFocusChanged import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.input.nestedscroll.nestedScroll import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.platform.LocalDensity @@ -188,7 +189,9 @@ private fun WalletContent2( } else { TangemTheme.colors2.surface.level2 }, - modifier = Modifier.matchParentSize(), + modifier = Modifier + .graphicsLayer { alpha = 1 - behavior.state.collapsedFraction * 2 } + .matchParentSize(), ) WalletPagerIndicator(