Skip to content

Commit 1b185aa

Browse files
committed
[Feature]
- Improved animation transition behavior for card stack interactions
1 parent 8ae680d commit 1b185aa

2 files changed

Lines changed: 36 additions & 46 deletions

File tree

library/ui/src/main/kotlin/tddy/ko/cardstack/ui/CardStack.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import androidx.compose.ui.unit.Density
3838
import androidx.compose.ui.unit.Dp
3939
import androidx.compose.ui.unit.dp
4040
import androidx.compose.ui.zIndex
41+
import kotlinx.coroutines.delay
4142
import kotlinx.coroutines.launch
4243

4344
/**
@@ -294,7 +295,7 @@ private fun DraggableCard(
294295
}
295296
.shadow(elevation = animatedElevation.dp, shape = RoundedCornerShape(12.dp))
296297
.then(
297-
if (index == 0 && !isAnimating) {
298+
if (!isAnimating) {
298299
Modifier.pointerInput(Unit) {
299300
val velocityTracker = VelocityTracker()
300301
detectDragGestures(
@@ -328,9 +329,11 @@ private fun DraggableCard(
328329
cardAlignment = cardAlignment
329330
)
330331
offset = targetOffset
332+
delay(10)
331333
updatedOnSwipe(direction)
332334
}
333335
offset = Offset.Zero
336+
delay(10)
334337
isAnimating = false
335338
}
336339
}

library/ui/src/main/kotlin/tddy/ko/cardstack/ui/CardStackHelper.kt

Lines changed: 32 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import androidx.compose.ui.graphics.GraphicsLayerScope
66
import androidx.compose.ui.unit.IntSize
77
import androidx.compose.ui.unit.Velocity
88
import kotlin.math.absoluteValue
9+
import kotlin.math.pow
910

1011
/**
1112
* Represents the possible directions for card swiping gestures.
@@ -111,8 +112,6 @@ internal fun calculateSwipeProgress(offset: Offset, velocityThresholdPx: Float):
111112
* Calculates the scale factor for each card in the stack.
112113
*
113114
* @param index The index of the card in the stack
114-
* @param itemCount Total number of cards
115-
* @param stackDragProgress The current drag progress of the stack
116115
* @return The calculated scale factor
117116
**/
118117
internal fun calculateScales(index: Int, itemCount: Int, stackDragProgress: Float): Float {
@@ -165,52 +164,40 @@ internal fun calculateDragBasedOffset(
165164
spacingPx: Float,
166165
itemCount: Int,
167166
cardAlignment: CardAlignment
168-
): Offset = when {
169-
index == itemCount - 1 && stackDragProgress < 0f -> {
170-
val progress = stackDragProgress * (itemCount - index)
171-
when (cardAlignment) {
172-
CardAlignment.TOP -> Offset(0f, -(spacingPx * progress) * progress)
173-
CardAlignment.BOTTOM -> Offset(0f, (spacingPx * progress) * progress)
174-
CardAlignment.TOP_START, CardAlignment.BOTTOM_START ->
175-
Offset(
176-
(spacingPx * progress) * progress,
177-
(spacingPx * progress) * progress * if (cardAlignment == CardAlignment.BOTTOM_START) 1 else -1
178-
)
179-
180-
CardAlignment.TOP_END, CardAlignment.BOTTOM_END ->
181-
Offset(
182-
-(spacingPx * progress) * progress,
183-
(spacingPx * progress) * progress * if (cardAlignment == CardAlignment.BOTTOM_END) 1 else -1
184-
)
185-
186-
CardAlignment.START -> Offset((spacingPx * progress) * progress, 0f)
187-
CardAlignment.END -> Offset(-(spacingPx * progress) * progress, 0f)
188-
}
167+
): Offset {
168+
val progress = if (index == itemCount - 1 && stackDragProgress < 0f) {
169+
(-stackDragProgress).coerceIn(0f, 1f)
170+
} else {
171+
(stackDragProgress * (1f - (index.toFloat() / itemCount))).coerceIn(-1f, 1f)
189172
}
190173

191-
index > 0 && stackDragProgress != 0f -> {
192-
val progress = (stackDragProgress * (itemCount - index)).coerceIn(0f, 1f)
193-
when (cardAlignment) {
194-
CardAlignment.TOP -> Offset(0f, -spacingPx * progress)
195-
CardAlignment.BOTTOM -> Offset(0f, spacingPx * progress)
196-
CardAlignment.TOP_START, CardAlignment.BOTTOM_START ->
197-
Offset(
198-
spacingPx * progress,
199-
spacingPx * progress * if (cardAlignment == CardAlignment.BOTTOM_START) 1 else -1
200-
)
201-
202-
CardAlignment.TOP_END, CardAlignment.BOTTOM_END ->
203-
Offset(
204-
-spacingPx * progress,
205-
spacingPx * progress * if (cardAlignment == CardAlignment.BOTTOM_END) 1 else -1
206-
)
207-
208-
CardAlignment.START -> Offset(spacingPx * progress, 0f)
209-
CardAlignment.END -> Offset(-spacingPx * progress, 0f)
210-
}
174+
val easedProgress = progress * progress * (3 - 2 * progress)
175+
176+
return when (cardAlignment) {
177+
CardAlignment.TOP -> Offset(
178+
0f,
179+
spacingPx * easedProgress * if (index == itemCount - 1 && stackDragProgress < 0f) 1f else -1f
180+
)
181+
CardAlignment.BOTTOM -> Offset(0f, spacingPx * easedProgress)
182+
CardAlignment.TOP_START -> Offset(
183+
spacingPx * easedProgress,
184+
-spacingPx * easedProgress
185+
)
186+
CardAlignment.BOTTOM_START -> Offset(
187+
spacingPx * easedProgress,
188+
spacingPx * easedProgress
189+
)
190+
CardAlignment.TOP_END -> Offset(
191+
-spacingPx * easedProgress,
192+
-spacingPx * easedProgress
193+
)
194+
CardAlignment.BOTTOM_END -> Offset(
195+
-spacingPx * easedProgress,
196+
spacingPx * easedProgress
197+
)
198+
CardAlignment.START -> Offset(spacingPx * easedProgress, 0f)
199+
CardAlignment.END -> Offset(-spacingPx * easedProgress, 0f)
211200
}
212-
213-
else -> Offset.Zero
214201
}
215202

216203
/**

0 commit comments

Comments
 (0)