Updated on 2026-08-14
This commit is contained in:
parent
d42cb2a79e
commit
00c5775f03
7 changed files with 70 additions and 29 deletions
|
|
@ -28,6 +28,7 @@ import com.arkivanov.decompose.value.Value
|
|||
import com.arkivanov.essenty.backhandler.BackHandler
|
||||
import com.tangem.common.routing.AppRoute
|
||||
import com.tangem.core.ui.UiDependencies
|
||||
import com.tangem.core.ui.components.haze.ProvideHaze
|
||||
import com.tangem.core.ui.components.snackbar.TangemSnackbarHost
|
||||
import com.tangem.core.ui.components.snackbar.TangemTopSnackbarHost
|
||||
import com.tangem.core.ui.message.EventMessageEffect
|
||||
|
|
@ -72,7 +73,9 @@ internal fun RootContent(
|
|||
when (val instance = child.instance) {
|
||||
is RoutingComponent.Child.Initial -> Unit
|
||||
is RoutingComponent.Child.ComposableComponent -> {
|
||||
instance.component.Content(Modifier.fillMaxSize())
|
||||
ProvideHaze {
|
||||
instance.component.Content(Modifier.fillMaxSize())
|
||||
}
|
||||
}
|
||||
is RoutingComponent.Child.LegacyIntent -> {
|
||||
// TODO: Remove and use it's own router: [REDACTED_JIRA]
|
||||
|
|
|
|||
|
|
@ -4,10 +4,12 @@ import androidx.compose.animation.core.CubicBezierEasing
|
|||
import androidx.compose.animation.core.FiniteAnimationSpec
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.CompositingStrategy
|
||||
import androidx.compose.ui.graphics.graphicsLayer
|
||||
import androidx.compose.ui.layout.layout
|
||||
import com.arkivanov.decompose.extensions.compose.stack.animation.*
|
||||
import com.tangem.common.routing.AppRoute
|
||||
import kotlin.math.abs
|
||||
|
||||
object RoutingTransitionAnimationFactory {
|
||||
|
||||
|
|
@ -18,13 +20,15 @@ object RoutingTransitionAnimationFactory {
|
|||
is AppRoute.Home,
|
||||
-> fade(tween(400)).plus(scale(tween(400)))
|
||||
is AppRoute.Wallet,
|
||||
-> slideAndFade(directions = setOf(Direction.ENTER_BACK, Direction.EXIT_BACK))
|
||||
.plus(
|
||||
scaleWithDirection(
|
||||
directions = setOf(Direction.ENTER_FRONT, Direction.EXIT_FRONT),
|
||||
animationSpec = tween(400),
|
||||
),
|
||||
)
|
||||
-> slideAndFade(
|
||||
slideDirections = setOf(Direction.ENTER_BACK, Direction.EXIT_BACK),
|
||||
fadeDirections = emptySet(),
|
||||
).plus(
|
||||
scaleWithDirection(
|
||||
directions = setOf(Direction.ENTER_FRONT, Direction.EXIT_FRONT),
|
||||
animationSpec = tween(400),
|
||||
),
|
||||
)
|
||||
else -> slideAndFade()
|
||||
}
|
||||
}
|
||||
|
|
@ -52,28 +56,64 @@ object RoutingTransitionAnimationFactory {
|
|||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param slideDirections directions in which the horizontal slide is applied.
|
||||
* `null` (default) means slide in all directions.
|
||||
* @param fadeDirections directions in which the alpha fade is applied.
|
||||
* `null` (default) means fade in all directions. Pass `emptySet()` to disable the fade
|
||||
* entirely — useful for screens that own a `hazeEffect` (e.g. WalletTopBar's progressive
|
||||
* blur), where wrapping the screen in an animated `graphicsLayer { alpha = ... }` causes
|
||||
* a visible blink over the blurred region.
|
||||
*/
|
||||
@Suppress("MagicNumber")
|
||||
private fun slideAndFade(directions: Set<Direction>? = null): StackAnimator {
|
||||
private fun slideAndFade(
|
||||
slideDirections: Set<Direction>? = null,
|
||||
fadeDirections: Set<Direction>? = null,
|
||||
): StackAnimator {
|
||||
val easing = CubicBezierEasing(a = 0.55f, b = 0.0f, c = 0.0f, d = 1f)
|
||||
|
||||
return stackAnimator(
|
||||
val slide = stackAnimator(
|
||||
animationSpec = tween(durationMillis = 400, easing = easing),
|
||||
) { factor, direction, content ->
|
||||
content(
|
||||
if (directions == null || directions.contains(direction)) {
|
||||
if (slideDirections == null || slideDirections.contains(direction)) {
|
||||
Modifier.offsetXFactor(factor)
|
||||
} else {
|
||||
Modifier
|
||||
},
|
||||
)
|
||||
}.plus(
|
||||
fade(
|
||||
animationSpec = tween(
|
||||
delayMillis = 50,
|
||||
durationMillis = 300,
|
||||
easing = easing,
|
||||
),
|
||||
}
|
||||
|
||||
val fade = directionalFade(
|
||||
animationSpec = tween(
|
||||
delayMillis = 50,
|
||||
durationMillis = 300,
|
||||
easing = easing,
|
||||
),
|
||||
directions = fadeDirections,
|
||||
)
|
||||
|
||||
return slide.plus(fade)
|
||||
}
|
||||
|
||||
/**
|
||||
* Like `decompose.fade(...)` but only applies the alpha `graphicsLayer` when `direction`
|
||||
* is in [directions]. `null` directions = always fade (matches stock `fade()` behavior).
|
||||
* `emptySet()` directions = never fade (modifier passes through untouched).
|
||||
*/
|
||||
private fun directionalFade(
|
||||
animationSpec: FiniteAnimationSpec<Float>,
|
||||
directions: Set<Direction>?,
|
||||
): StackAnimator = stackAnimator(animationSpec) { factor, direction, content ->
|
||||
content(
|
||||
if (directions == null || directions.contains(direction)) {
|
||||
Modifier.graphicsLayer {
|
||||
alpha = 1f - abs(factor)
|
||||
compositingStrategy = CompositingStrategy.Offscreen
|
||||
}
|
||||
} else {
|
||||
Modifier
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue