Skip to content

Commit

Permalink
library: Optimize Popup Animation (#26)
Browse files Browse the repository at this point in the history
  • Loading branch information
HowieHChen authored Oct 20, 2024
1 parent 6bcce1a commit 52130a6
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 21 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package top.yukonga.miuix.kmp.anim

import androidx.compose.animation.core.Easing
import androidx.compose.runtime.Immutable
import kotlin.math.pow

/**
* This is equivalent to the Android [AccelerateInterpolator](https://cs.android.com/search?q=file:androidx/core/animation/AccelerateInterpolator.java+class:androidx.core.animation.AccelerateInterpolator)
*
* @param factor Degree to which the animation should be eased. Setting
* factor to 1.0f produces a y=x^2 parabola. Increasing factor above
* 1.0f exaggerates the ease-in effect (i.e., it starts even
* slower and ends evens faster)
*/
@Immutable
class AccelerateEasing(
private val factor: Float = 1.0f
) : Easing {
private val doubleFactor: Float = 2 * factor

override fun transform(fraction: Float): Float {
return if (factor == 1.0f) {
fraction * fraction
} else {
fraction.pow(doubleFactor)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@


package top.yukonga.miuix.kmp.anim

import androidx.compose.animation.core.Easing
import androidx.compose.runtime.Immutable
import kotlin.math.pow

/**
* This is equivalent to the Android [DecelerateInterpolator](https://cs.android.com/search?q=file:androidx/core/animation/DecelerateInterpolator.java+class:androidx.core.animation.DecelerateInterpolator)
*
* @param factor Degree to which the animation should be eased. Setting factor to 1.0f produces
* an upside-down y=x^2 parabola. Increasing factor above 1.0f makes exaggerates the
* ease-out effect (i.e., it starts even faster and ends evens slower)
*/
@Immutable
class DecelerateEasing(
private val factor: Float = 1.0f
) : Easing {
override fun transform(fraction: Float): Float {
return if (factor == 1.0f) {
1.0f - (1.0f - fraction) * (1.0f - fraction)
} else {
1.0f - (1.0f - fraction).pow(2 * fraction)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,23 +1,28 @@
package top.yukonga.miuix.kmp.utils

import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.core.CubicBezierEasing
import androidx.compose.animation.core.spring
import androidx.compose.animation.core.tween
import androidx.compose.animation.expandIn
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.scaleIn
import androidx.compose.animation.scaleOut
import androidx.compose.animation.shrinkOut
import androidx.compose.animation.slideInVertically
import androidx.compose.animation.slideOutVertically
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.dp
import androidx.compose.ui.zIndex
import top.yukonga.miuix.kmp.anim.AccelerateEasing
import top.yukonga.miuix.kmp.anim.DecelerateEasing
import top.yukonga.miuix.kmp.basic.Box
import top.yukonga.miuix.kmp.basic.Scaffold
import top.yukonga.miuix.kmp.theme.MiuixTheme
Expand Down Expand Up @@ -90,11 +95,16 @@ class MiuixPopupUtil {
*/
@Composable
fun MiuixPopupHost() {
val density = LocalDensity.current
val getWindowSize by rememberUpdatedState(getWindowSize())
val windowWidth by rememberUpdatedState(getWindowSize.width.dp / density.density)
val windowHeight by rememberUpdatedState(getWindowSize.height.dp / density.density)
val largeScreen by rememberUpdatedState { derivedStateOf { (windowHeight >= 480.dp && windowWidth >= 840.dp) } }
AnimatedVisibility(
visible = isDialogShowing.value || isPopupShowing.value,
modifier = Modifier.zIndex(1f).fillMaxSize(),
enter = fadeIn(animationSpec = tween(500)),
exit = fadeOut(animationSpec = tween(500))
enter = fadeIn(animationSpec = tween(300, easing = DecelerateEasing(1.5f))),
exit = fadeOut(animationSpec = tween(250, easing = DecelerateEasing(1.5f)))
) {
Box(
modifier = Modifier
Expand All @@ -105,20 +115,32 @@ class MiuixPopupUtil {
AnimatedVisibility(
visible = isDialogShowing.value,
modifier = Modifier.zIndex(2f).fillMaxSize(),
enter = slideInVertically(
initialOffsetY = { fullHeight -> fullHeight },
animationSpec = tween(
durationMillis = 500,
easing = CubicBezierEasing(0f, 1f, 0.36f, 1f)
enter = if (largeScreen.invoke().value) {
fadeIn(
animationSpec = spring(0.9f, 900f)
) + scaleIn(
initialScale = 0.8f,
animationSpec = spring(0.73f, 900f)
)
),
exit = slideOutVertically(
targetOffsetY = { fullHeight -> fullHeight },
animationSpec = tween(
durationMillis = 300,
easing = CubicBezierEasing(1f, 0f, 0.64f, 0f)
} else {
slideInVertically(
initialOffsetY = { fullHeight -> fullHeight },
animationSpec = spring(0.92f, 500f)
)
)
},
exit = if (largeScreen.invoke().value) {
fadeOut(
animationSpec = tween(200, easing = DecelerateEasing(1.5f))
) + scaleOut(
targetScale = 0.8f,
animationSpec = tween(200, easing = DecelerateEasing(1.5f))
)
} else {
slideOutVertically(
targetOffsetY = { fullHeight -> fullHeight },
animationSpec = tween(200, easing = DecelerateEasing(1.5f))
)
}
) {
Box(
modifier = Modifier.fillMaxSize()
Expand All @@ -140,14 +162,16 @@ class MiuixPopupUtil {
visible = isPopupShowing.value,
modifier = Modifier.zIndex(2f).fillMaxSize(),
enter = fadeIn(
animationSpec = tween(150)
animationSpec = tween(150, easing = DecelerateEasing(1.5f))
) + scaleIn(
animationSpec = tween(150), initialScale = 0.9f
initialScale = 0.8f,
animationSpec = tween(150, easing = DecelerateEasing(1.5f))
),
exit = fadeOut(
animationSpec = tween(150)
animationSpec = tween(150, easing = AccelerateEasing(3.0f))
) + scaleOut(
animationSpec = tween(150), targetScale = 0.9f
targetScale = 0.8f,
animationSpec = tween(150, easing = AccelerateEasing(3.0f))
)
) {
Box(
Expand Down

0 comments on commit 52130a6

Please sign in to comment.