feat: Enhance avatar animation with sharp expansion effect for smoother transitions

This commit is contained in:
k1ngsterr1
2026-01-31 04:03:43 +05:00
parent e9386c21dc
commit 3ed4986393

View File

@@ -757,6 +757,10 @@ private fun CollapsingProfileHeader(
// Зона аватарки = ВСЯ высота header включая статус бар // Зона аватарки = ВСЯ высота header включая статус бар
val avatarZoneHeight = EXPANDED_HEADER_HEIGHT + statusBarHeight val avatarZoneHeight = EXPANDED_HEADER_HEIGHT + statusBarHeight
// Резкая анимация - используем easeOut (быстро в начале, медленно в конце)
// sqrt делает анимацию более резкой/быстрой
val sharpExpansion = kotlin.math.sqrt(expansionProgress.toDouble()).toFloat()
// При overscroll расширяем до прямоугольника на всю зону (только если не collapsed И есть // При overscroll расширяем до прямоугольника на всю зону (только если не collapsed И есть
// аватарка) // аватарка)
val avatarWidth: Dp val avatarWidth: Dp
@@ -764,9 +768,9 @@ private fun CollapsingProfileHeader(
if (hasAvatar && collapseProgress < 0.1f && expansionProgress > 0f) { if (hasAvatar && collapseProgress < 0.1f && expansionProgress > 0f) {
// Overscroll: круг -> прямоугольник на всю зону ВКЛЮЧАЯ статус бар (ТОЛЬКО С АВАТАРКОЙ) // Overscroll: круг -> прямоугольник на всю зону ВКЛЮЧАЯ статус бар (ТОЛЬКО С АВАТАРКОЙ)
avatarWidth = androidx.compose.ui.unit.lerp(circleSize, screenWidthDp, expansionProgress) // Используем sharpExpansion для резкой анимации
avatarHeight = avatarWidth = androidx.compose.ui.unit.lerp(circleSize, screenWidthDp, sharpExpansion)
androidx.compose.ui.unit.lerp(circleSize, avatarZoneHeight, expansionProgress) avatarHeight = androidx.compose.ui.unit.lerp(circleSize, avatarZoneHeight, sharpExpansion)
} else { } else {
// Collapse: сразу начинаем уменьшаться от круга до 0 // Collapse: сразу начинаем уменьшаться от круга до 0
val collapsedSize = androidx.compose.ui.unit.lerp(circleSize, 0.dp, collapseProgress) val collapsedSize = androidx.compose.ui.unit.lerp(circleSize, 0.dp, collapseProgress)
@@ -787,7 +791,8 @@ private fun CollapsingProfileHeader(
val avatarY = val avatarY =
if (hasAvatar && collapseProgress < 0.1f && expansionProgress > 0f) { if (hasAvatar && collapseProgress < 0.1f && expansionProgress > 0f) {
// При overscroll прижимаемся к самому верху (ТОЛЬКО С АВАТАРКОЙ) // При overscroll прижимаемся к самому верху (ТОЛЬКО С АВАТАРКОЙ)
androidx.compose.ui.unit.lerp(defaultCenterY, topAvatarY, expansionProgress) // Используем sharpExpansion для резкой анимации
androidx.compose.ui.unit.lerp(defaultCenterY, topAvatarY, sharpExpansion)
} else { } else {
// Collapse: сразу начинаем уходить вверх // Collapse: сразу начинаем уходить вверх
androidx.compose.ui.unit.lerp( androidx.compose.ui.unit.lerp(
@@ -797,12 +802,12 @@ private fun CollapsingProfileHeader(
) )
} }
// Закругление: круг по умолчанию, при overscroll становится квадратом БЕЗ скругления (ТОЛЬКО С // Закругление: круг по умолчанию, при overscroll плавно становится квадратом (ТОЛЬКО С
// АВАТАРКОЙ) // АВАТАРКОЙ)
val cornerRadius = val cornerRadius =
if (hasAvatar && collapseProgress < 0.1f && expansionProgress > 0f) { if (hasAvatar && collapseProgress < 0.1f && expansionProgress > 0f) {
// Overscroll: круг -> квадрат без скругления // Overscroll: круг -> квадрат без скругления (резкая анимация)
androidx.compose.ui.unit.lerp(avatarSize / 2, 0.dp, expansionProgress) androidx.compose.ui.unit.lerp(avatarSize / 2, 0.dp, sharpExpansion)
} else { } else {
// Всегда круг // Всегда круг
avatarSize / 2 avatarSize / 2