Add rotate inertia for favSelectDialog
This commit is contained in:
1 parent
fa2933df7c
commit
aa50b69754
1 file changed
+27
-1
@@ -1,9 +1,14 @@
|
||||
package com.hippo.ehviewer.ui.tools
|
||||
|
||||
import androidx.compose.animation.core.FloatExponentialDecaySpec
|
||||
import androidx.compose.animation.core.animateDecay
|
||||
import androidx.compose.foundation.gestures.draggable2D
|
||||
import androidx.compose.foundation.gestures.rememberDraggable2DState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableFloatStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.geometry.Offset
|
||||
@@ -14,6 +19,8 @@ import kotlin.math.atan2
|
||||
import kotlin.math.cos
|
||||
import kotlin.math.roundToInt
|
||||
import kotlin.math.sin
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
private const val FULL_CIRCLE: Float = (PI * 2).toFloat()
|
||||
private const val QUARTER_CIRCLE = PI / 2
|
||||
@@ -21,13 +28,17 @@ private const val QUARTER_CIRCLE = PI / 2
|
||||
private var currentTheta: Float? = null
|
||||
private var currentOfs: Offset? = null
|
||||
|
||||
private val rotateDecay = FloatExponentialDecaySpec()
|
||||
private var animJob: Job? = null
|
||||
|
||||
@Composable
|
||||
fun CircularLayout(
|
||||
modifier: Modifier = Modifier,
|
||||
placeFirstItemInCenter: Boolean = false,
|
||||
content: @Composable () -> Unit,
|
||||
) {
|
||||
var delta by Settings::favDialogTheta.observed
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
var delta by remember { mutableFloatStateOf(Settings.favDialogTheta) }
|
||||
val state = rememberDraggable2DState {
|
||||
val prevOfs = currentOfs
|
||||
val prevTheta = currentTheta
|
||||
@@ -46,12 +57,27 @@ fun CircularLayout(
|
||||
onDragStarted = {
|
||||
// Get relative offset to center
|
||||
val ofs = it - Offset(500f, 500f)
|
||||
animJob?.cancel()
|
||||
currentOfs = ofs
|
||||
currentTheta = atan2(ofs.y, ofs.x)
|
||||
},
|
||||
onDragStopped = {
|
||||
val current = currentOfs
|
||||
if (current != null) {
|
||||
val dist = current.getDistance()
|
||||
val tanVec = Offset(-current.y / dist, current.x / dist)
|
||||
val tanV = it.x * tanVec.x + it.y * tanVec.y
|
||||
val omega = tanV / dist
|
||||
animJob = coroutineScope.launch {
|
||||
animateDecay(delta, omega, rotateDecay) { d, _ ->
|
||||
delta = d
|
||||
}
|
||||
Settings.favDialogTheta = delta
|
||||
}
|
||||
}
|
||||
currentOfs = null
|
||||
currentTheta = null
|
||||
Settings.favDialogTheta = delta
|
||||
},
|
||||
),
|
||||
content = content,
|
||||
|
||||
Reference in new issue
Block a user