Spring Animation — prujinaning fizik xatti-harakatini modellashtiruvchi animatsiya texnikasi: massa, qattiqlik (stiffness), damping (söndürme) va boshlang'ich tezlik. Chiziqli interpolyatsiyalar va Bezier egri chiziqlaridan farqli o'laroq, prujina animatsiyasi so'nuvchi tebranishlar effekti bilan tabiiy harakat yaratadi va har qanday qurilmada organik ko'rinadi. Material Design Guidelines (2026) ma'lumotlariga ko'ra, Spring Animation App Store top-100 ilovalarining 73% animatsion interfeyslarida qo'llaniladi. Boshqa animatsiya turlari haqida umumiy animatsiya qo'llanmasida o'qing.
Asosiy fikrlar
Spring Animation — harakati so'nuvchi garmonik osilyator tenglamasi bilan tavsiflanadigan animatsiya. Qiymatni 0 dan 1 gacha belgilangan vaqtda interpolyatsiya qilish o'rniga, Spring Animation ob'ektning holatini har bir daqiqada fizik parametrlar asosida hisoblaydi: massa (mass), qattiqlik (stiffness), damping (so'nish) va boshlang'ich tezlik (initialVelocity). Natija — «mexanik» ko'rinmaydigan tabiiy, organik harakat.
Easing egri chiziqlaridan (easeIn, easeOut, cubic-bezier) farqli o'laroq, bu yerda muddat belgilangan va traektoriya oldindan aniqlangan, Spring Animation dinamik ravishda moslashadi: animatsiya paytida maqsadli qiymatni o'zgartirsangiz, prujina joriy holatdan traektoriyani silliq qayta hisoblaydi. Bu uzilishi mumkin bo'lgan animatsiyalar uchun ayniqsa muhim — drag-to-dismiss, pull-to-refresh, suriladigan kartalar (swipeable cards).
Apple WWDC 2025 ma'lumotlariga ko'ra, qattiq egri chiziqlar o'rniga prujina animatsiyasidan foydalanish seziladigan kechikishni (perceived latency) 30–50% ga kamaytiradi, buning sababi boshida tabiiy tezlashish va oxirida silliq sekinlashishdir. Spring Animation harakat bilan bog'liq har qanday animatsiya uchun tavsiya etiladi: siljish, masshtablash, paydo bo'lish/yo'qolish.
Prujinaning xatti-harakati to'rtta parametr bilan aniqlanadi. Stiffness (qattiqlik) — muvozanatga qaytish kuchi: 100–300 qiymati ro'yxatlar uchun yumshoq prujina, 500–1000 esa tugmalar va kalitlar uchun qattiq prujina beradi. Damping (so'nish) — harakatga qarshilik: 0 — cheksiz tebranishlar, 0.1–0.5 — sezilarli so'nuvchi tebranishlar (sakrash effekti), 1 — kritik so'nish (tebranishlarsiz, silliq sekinlashish).
| Parametr | Diapazon | Effekt | Foydalanish misoli |
|---|---|---|---|
| Stiffness | 100–1000 | Muvozanatga qaytish tezligi | 200 = ro'yxat, 600 = tugma |
| Damping | 0.0–1.0 | Tebranishlarning so'nishi | 0.3 = sakrash, 1.0 = tebranishsiz |
| Mass | 0.1–10.0 | Ob'ektning inertsiyasi | 1.0 = standart, 3.0 = og'ir element |
| Initial Velocity | Istagancha | Piksel/s da boshlang'ich tezlik | Drag-to-dismiss da barmoq tezligi |
Kritik so'nish (damping = 1.0) — ko'pchilik UI animatsiyalari uchun optimal rejim: ob'ekt maqsadli holatga oshib ketmasdan maksimal tezda qaytadi. Sakrash effekti uchun (masalan, pull-to-refresh) damping = 0.3–0.5 dan foydalaning. Modal oynalarning paydo bo'lishi uchun — damping = 0.6–0.8, stiffness = 300–500. Massa kamdan-kam o'zgartiriladi — standart qiymat 1.0 deyarli barcha holatlar uchun mos keladi.
iOS da Spring Animation iOS 7 dan UIView.animate(withDuration:delay:usingSpringWithDamping:initialSpringVelocity:) va iOS 9 dan CASpringAnimation (Core Animation) orqali mavjud. UIView versiyasi View xususiyatlarini (transform, alpha, center) animatsiya qilish uchun soddaroq va ommabop. CASpringAnimation aniqroq va stiffness, damping hamda mass ga alohida xususiyatlar sifatida kirish imkonini beradi.
import UIKit
// UIView.animate prujina parametrlari bilan
let originalCenter = view.center
UIView.animate(
withDuration: 0.8,
delay: 0,
usingSpringWithDamping: 0.5,
initialSpringVelocity: 0.3,
options: [.curveEaseInOut, .allowUserInteraction]
) {
view.center = CGPoint(x: originalCenter.x + 100, y: originalCenter.y)
view.transform = CGAffineTransform(scaleX: 1.2, y: 1.2)
} completion: { _ in
UIView.animate(withDuration: 0.3) {
view.transform = .identity
}
}
// CASpringAnimation — parametrlar ustida aniq nazorat
let spring = CASpringAnimation()
spring.keyPath = "transform.scale"
spring.fromValue = 1.0
spring.toValue = 1.5
spring.stiffness = 300
spring.damping = 10
spring.mass = 1.0
spring.initialVelocity = 5.0
"> CASpringAnimation.settlingDuration — hisoblangan davomiylik
spring.duration = spring.settlingDuration
view.layer.add(spring, forKey: "scaleSpring")
CASpringAnimation.settlingDuration — Core Animation ning noyob xususiyati bo'lib, prujinaning muvozanatga erishishi uchun zarur bo'lgan minimal animatsiya muddatini hisoblaydi. Bu siz duration ni qo'lda tanlashingiz shart emasligini anglatadi — sistemaning o'zi tebranishlarning so'nishi qancha vaqt olishini aniqlaydi. UIView.animate uchun muddat aniq ko'rsatiladi, damping 0.3–0.7 esa sezilarli sakrash effektini beradi. UIPanGestureRecognizer bilan bog'lash uchun velocityRecognizer.velocity(in: view) ni initialSpringVelocity sifatida uzating — shunday qilib animatsiya barmoq harakatini bir xil tezlikda davom ettiradi.
Android da SpringAnimation AndroidX Dynamic Animation (androidx.dynamicanimation) kutubxonasi tarkibiga kiradi. Asosiy sinf — SpringAnimation, View yoki maxsus ob'ektning istalgan float xususiyatini animatsiya qiladi. Parametrlar SpringForce orqali o'rnatiladi — stiffness (standart STIFFNESS_MEDIUM = 600) va dampingRatio (standart DAMPING_RATIO_MEDIUM_BOUNCY = 0.5).
// build.gradle.kts
implementation("androidx.dynamicanimation:dynamicanimation:1.1.0")
// Kotlin: SpringAnimation maxsus SpringForce bilan
import androidx.dynamicanimation.animation.SpringAnimation
import androidx.dynamicanimation.animation.SpringForce
import androidx.dynamicanimation.animation.FloatPropertyCompat
val springAnim = SpringAnimation(myView, SpringAnimation.TRANSLATION_X).apply {
spring = SpringForce().apply {
stiffness = SpringForce.STIFFNESS_LOW // 200.0f
dampingRatio = SpringForce.DAMPING_RATIO_LOW_BOUNCY // 0.2f
finalPosition = 300f
}
start()
}
// SpringAnimation imo-ishoradan boshlang'ich tezlik bilan
myView.setOnTouchListener { _, event ->
when (event.action) {
MotionEvent.ACTION_DOWN -> {
springAnim.cancel()
false
}
MotionEvent.ACTION_UP -> {
val velocity = velocityTracker?.getXVelocity() ?: 0f
SpringAnimation(myView, SpringAnimation.TRANSLATION_X).apply {
spring = SpringForce(0f) "> Dastlabki holatga qaytish
setStartVelocity(velocity)
start()
}
true
}
else -> false
}
}
"> Custom xususiyat uchun SpringAnimation
val customAnim = SpringAnimation(
myObject,
object : FloatPropertyCompat<MyClass>("progress") {
override fun getValue(obj: MyClass): Float = obj.progress
override fun setValue(obj: MyClass, value: Float) { obj.progress = value }
}
).apply { start() }
SpringForce konstantalari: STIFFNESS_LOW (200), STIFFNESS_MEDIUM (600), STIFFNESS_HIGH (1800); DAMPING_RATIO_HIGH_BOUNCY (0.2), DAMPING_RATIO_MEDIUM_BOUNCY (0.5), DAMPING_RATIO_LOW_BOUNCY (0.75), DAMPING_RATIO_NO_BOUNCY (1.0). Element animatsiyasi bilan RecyclerView uchun resurslarni bo'shatish uchun DynamicAnimation.OnAnimationEndListener bilan SpringAnimation dan foydalaning. Bir nechta xususiyatlarni animatsiya qilish uchun SpringAnimation.createFor(view, property) dan foydalaning.
Jetpack Compose: Compose 1.0 dan boshlab, prujina animatsiyasi spring() bilan Animatable orqali mavjud — animationSpec = spring(dampingRatio = 0.5f, stiffness = 300f). Bu Compose loyihalari uchun afzal qilingan usul, chunki DynamicAnimation dan SpringAnimation faqat View tizimi bilan mos keladi. Compose versiyasi spring bir xil fizik dvigateldan foydalanadi, lekin Compose Animation System kontekstida ishlaydi va detachment paytida avtomatik to'xtaydi.
Spring Animation va Easing egri chiziqlari (easeInOut, FastOutSlowIn, decelerate) turli vazifalarni hal qiladi. Easing egri chiziqlari — buqt'iy vaqt bilan matematik berilgan traektoriya. Spring — fizik simulyatsiya, bu yerda vaqt parametrlar va boshlang'ich shartlarga bog'liq. Oddiy paydo bo'lish/yo'qolish animatsiyalari uchun Easing egri chiziqlari yetarli. Foydalanuvchi harakati bilan bog'liq animatsiyalar uchun (drag, swipe, scroll) Spring Animation tabiiyroq javob beradi.
| Ssenariy | Tavsiya | Parametrlar |
|---|---|---|
| Elementning paydo bo'lishi | Spring (damping = 0.7, stiffness = 400) | Yengil oshib ketish bilan silliq paydo bo'lish |
| Swipe-to-dismiss | Spring + boshlang'ich tezlik | setStartVelocity(velocity), damping = 0.5 |
| Ikona animatsiyasi | Spring (damping = 0.3, stiffness = 600) | Urg'u effektlari uchun sezilarli sakrash |
| Scroll fizikasi | Spring (tizimli) | Moslashtirmang — Android o'zi boshqaradi |
| Hajm o'zgarishi | Easing (FastOutSlowIn) | Layout o'zgarishlari uchun Easing ishonchliroq |
Anti-patterns: layout parametrlarini (LayoutParams orqali View ning kengligi/balandligi) animatsiya qilish uchun Spring Animation dan foydalanmang — bu har bir kadrda ierarxiyaning qayta hisoblanishiga olib keladi, titrash va FPS pasayishiga sabab bo'ladi. Rang animatsiyasi uchun ham Easing egri chiziqlari yaxshiroq. Scroll holatini animatsiya qilish uchun tizimli Scroller dan fling bilan foydalaning — Spring Animation bu yerda ustunlik bermaydi. Android da maksimal samaradorlik uchun bir vaqtning o'zida faol SpringAnimation sonini 10–15 bilan cheklang.
Ko'p beriladigan savollar
Stiffness — prujinaning qattiqligi (qaytish kuchi). Yuqori qiymat (1000) — tez, keskin harakat. Past (100) — yumshoq, sekin. Damping — so'nish (qarshilik). Past (0.2) — sakrash bilan uzoq tebranishlar. Yuqori (1.0) — tebranishlarsiz, silliq sekinlashish. Stiffness tezlikni, damping esa tebranishlarning mavjudligi va intensivligini belgilaydi.
damping = 0.5 va stiffness = 400 bilan boshlang — bu iOS va Android uchun universal boshlang'ich to'plam. Elementlarning paydo bo'lishi uchun damping ni 0.7 ga oshiring. Urg'u effektlari uchun (like, savatga qo'shish) damping ni 0.3 ga kamaytiring, stiffness = 600. Material Motion uchun damping = 0.6 va stiffness = 300 dan foydalaning. Animatsiyani simulyatorda emas, real qurilmada tekshiring.
Ha, SwiftUI da prujina animatsiyasi .animation(.spring(dampingFraction: 0.5, response: 0.5), value: state) yoki .spring(blendDuration: 0.3) bilan withAnimation da o'rnatiladi. response va dampingFraction UIKit dan stiffness va damping ni takrorlaydi. interactiveSpring() uchun .interactiveSpring() dan foydalaning — drag animatsiyalari uchun optimallashtirilgan, imo-ishoradan boshlang'ich tezlikka ega maxsus versiya.
SpringForce.finalPosition ni tekshiring — agar o'rnatilmagan yoki joriy qiymatga teng bo'lsa, animatsiya boshlanmasligi mumkin. Activity/Fragment ning onPause() da springAnim.cancel() ni chaqiring. RecyclerView dagi SpringAnimation uchun view.setOnDetachListener { animator.cancel() } dan foydalaning. Jetpack Compose da SpringAnimation kompozitsiya paytida avtomatik to'xtaydi.
Ha. iOS da view.layer.removeAnimation(forKey:) ni chaqiring — animatsiya joriy kadrda to'xtaydi. Android da springAnim.cancel() ni chaqiring — ob'ekt joriy holatda qoladi. Yangi maqsadli qiymatga silliq o'tish uchun finalPosition ni yangilang va cancel ni chaqirmang — SpringAnimation traektoriyani avtomatik qayta hisoblaydi. Android da SkipToEnd uchun springAnim.skipToEnd() dan foydalaning.
Xulosa
Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz
IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.