61 lines
2.2 KiB
Kotlin
61 lines
2.2 KiB
Kotlin
package eu.kanade.presentation.util
|
|
|
|
import androidx.compose.animation.core.AnimationState
|
|
import androidx.compose.animation.core.DecayAnimationSpec
|
|
import androidx.compose.animation.core.animateDecay
|
|
import androidx.compose.animation.rememberSplineBasedDecay
|
|
import androidx.compose.foundation.gestures.FlingBehavior
|
|
import androidx.compose.foundation.gestures.ScrollScope
|
|
import androidx.compose.runtime.Composable
|
|
import androidx.compose.runtime.remember
|
|
import androidx.compose.ui.MotionDurationScale
|
|
import kotlinx.coroutines.withContext
|
|
import kotlin.math.abs
|
|
|
|
/**
|
|
* FlingBehavior that always uses the default motion scale.
|
|
*
|
|
* This makes the scrolling animation works like View's lists
|
|
* when "Remove animation" settings is on.
|
|
*/
|
|
@Composable
|
|
fun flingBehaviorIgnoringMotionScale(): FlingBehavior {
|
|
val flingSpec = rememberSplineBasedDecay<Float>()
|
|
return remember(flingSpec) {
|
|
DefaultFlingBehavior(flingSpec)
|
|
}
|
|
}
|
|
|
|
private val DefaultMotionDurationScale = object : MotionDurationScale {
|
|
// Use default motion scale factor
|
|
override val scaleFactor: Float = 1f
|
|
}
|
|
|
|
private class DefaultFlingBehavior(
|
|
private val flingDecay: DecayAnimationSpec<Float>,
|
|
) : FlingBehavior {
|
|
override suspend fun ScrollScope.performFling(initialVelocity: Float): Float {
|
|
// come up with the better threshold, but we need it since spline curve gives us NaNs
|
|
return if (abs(initialVelocity) > 1f) {
|
|
var velocityLeft = initialVelocity
|
|
var lastValue = 0f
|
|
withContext(DefaultMotionDurationScale) {
|
|
AnimationState(
|
|
initialValue = 0f,
|
|
initialVelocity = initialVelocity,
|
|
).animateDecay(flingDecay) {
|
|
val delta = value - lastValue
|
|
val consumed = scrollBy(delta)
|
|
lastValue = value
|
|
velocityLeft = this.velocity
|
|
// avoid rounding errors and stop if anything is unconsumed
|
|
if (abs(delta - consumed) > 0.5f) this.cancelAnimation()
|
|
}
|
|
}
|
|
velocityLeft
|
|
} else {
|
|
initialVelocity
|
|
}
|
|
}
|
|
}
|