feat: show tilted birthday crown with click bounce animation
This commit is contained in:
parent
f33e68d1db
commit
de47509a32
@ -1,9 +1,12 @@
|
||||
package plus.rua.project.ui
|
||||
|
||||
import androidx.compose.animation.animateColor
|
||||
import androidx.compose.animation.core.Animatable
|
||||
import androidx.compose.animation.core.FastOutSlowInEasing
|
||||
import androidx.compose.animation.core.Spring
|
||||
import androidx.compose.animation.core.animateFloat
|
||||
import androidx.compose.animation.core.animateFloatAsState
|
||||
import androidx.compose.animation.core.spring
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.animation.core.updateTransition
|
||||
import androidx.compose.ui.graphics.TransformOrigin
|
||||
@ -16,14 +19,19 @@ import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.aspectRatio
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableIntStateOf
|
||||
import androidx.compose.runtime.produceState
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
@ -31,6 +39,7 @@ import androidx.compose.ui.draw.drawBehind
|
||||
import androidx.compose.ui.geometry.Offset
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.drawscope.Stroke
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.semantics.contentDescription
|
||||
import androidx.compose.ui.semantics.semantics
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
@ -44,6 +53,7 @@ import kotlinx.datetime.number
|
||||
import plus.rua.project.DayCellInfo
|
||||
import plus.rua.project.LunarCache
|
||||
import plus.rua.project.ShiftKind
|
||||
import plus.rua.project.shared.R
|
||||
|
||||
enum class DayCellState {
|
||||
NORMAL, OTHER_MONTH, TODAY, SELECTED, SELECTED_TODAY
|
||||
@ -63,6 +73,9 @@ enum class DayCellState {
|
||||
* @param holidayEdgeInfo 假日在连续序列中的边缘状态,决定背景圆角。null 表示无假日。
|
||||
* @param cellIndex 单元格在月网格中的线性索引(weekIndex*7+dayIndex),用于法定假日波浪动画延迟。
|
||||
* @param onClick 点击回调
|
||||
* @param interactionSource 点击交互源
|
||||
* @param lunarCache 农历缓存实例
|
||||
* @param lunarData 预计算的日期信息;null 时内部自动获取
|
||||
* @param modifier 外部布局修饰符
|
||||
*/
|
||||
@Composable
|
||||
@ -76,10 +89,10 @@ fun DayCell(
|
||||
holidayEdgeInfo: HolidayEdgeInfo? = null,
|
||||
cellIndex: Int = 0,
|
||||
onClick: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
|
||||
lunarCache: LunarCache = LunarCache.default,
|
||||
lunarData: DayCellInfo? = null,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
if (lunarData != null) {
|
||||
DayCellImpl(
|
||||
@ -136,6 +149,16 @@ private fun DayCellImpl(
|
||||
interactionSource: MutableInteractionSource,
|
||||
lunarData: DayCellInfo,
|
||||
) {
|
||||
val isBirthday = lunarData.isBirthday
|
||||
var birthdayClickTick by remember(date) { mutableIntStateOf(0) }
|
||||
val crownScale = remember(date) { Animatable(1f) }
|
||||
LaunchedEffect(birthdayClickTick) {
|
||||
if (birthdayClickTick > 0) {
|
||||
crownScale.animateTo(1.4f, spring(dampingRatio = Spring.DampingRatioMediumBouncy))
|
||||
crownScale.animateTo(1f, spring(dampingRatio = Spring.DampingRatioMediumBouncy))
|
||||
}
|
||||
}
|
||||
|
||||
val annotationText = lunarData.annotationText
|
||||
val isAnnotationHighlight = lunarData.isAnnotationHighlight
|
||||
val holidayBadge = lunarData.holidayBadge
|
||||
@ -296,7 +319,10 @@ private fun DayCellImpl(
|
||||
.clickable(
|
||||
interactionSource = interactionSource,
|
||||
indication = null,
|
||||
onClick = onClick
|
||||
onClick = {
|
||||
if (isBirthday) birthdayClickTick += 1
|
||||
onClick()
|
||||
}
|
||||
),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
@ -346,5 +372,23 @@ private fun DayCellImpl(
|
||||
)
|
||||
}
|
||||
}
|
||||
if (isBirthday) {
|
||||
Icon(
|
||||
painter = painterResource(R.drawable.ic_birthday_crown),
|
||||
contentDescription = "生日",
|
||||
tint = Color.Unspecified,
|
||||
modifier = Modifier
|
||||
.align(Alignment.TopStart)
|
||||
.zIndex(1f)
|
||||
.padding(start = 2.dp, top = 2.dp)
|
||||
.size(14.dp)
|
||||
.graphicsLayer {
|
||||
rotationZ = -45f
|
||||
transformOrigin = TransformOrigin.Center
|
||||
scaleX = crownScale.value
|
||||
scaleY = crownScale.value
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user