Spring Animation — yayın fiziki davranışını modelləşdirən animasiya texnikası: kütlə, sərtlik (stiffness), sönümləmə (damping) və başlanğıc sürət. Xətti interpolasiyalardan və Bezier əyrilərindən fərqli olaraq, yay animasiyası sönümlənən rəqslər effekti ilə təbii hərəkət yaradır və istənilən cihazda organik görünür. Material Design Guidelines (2026) məlumatına görə, Spring Animation App Store-un top-100 tətbiqinin animasiyalı interfeyslərinin 73%-də istifadə olunur. Digər animasiya növləri haqqında ümumi animasiya bələdçisində oxuyun.
Əsas məqamlar
Spring Animation — hərəkəti sönümləmə ilə harmonik osilyator tənliyi ilə təsvir edilən animasiyadır. Sabit vaxt ərzində dəyəri 0-dan 1-ə interpolasiya etmək əvəzinə, Spring Animation fiziki parametrlərə əsasən obyektin mövqeyini hər an hesablayır: kütlə (mass), sərtlik (stiffness), sönümləmə (damping) və başlanğıc sürət (initialVelocity). Nəticə — "mexaniki" görünməyən təbii, organik hərəkətdir.
Easing əyrilərindən (easeIn, easeOut, cubic-bezier) fərqli olaraq, burada müddət sabit və trayektoriya əvvəlcədən müəyyən edilmişdir, Spring Animation dinamik olaraq uyğunlaşır: animasiya zamanı hədəf dəyəri dəyişdirsəniz, yay cari mövqedən trayektoriyanı rəvan yenidən hesablayır. Bu, kəsilə bilən animasiyalar üçün xüsusilə vacibdir — drag-to-dismiss, pull-to-refresh, sürüşdürülən kartlar (swipeable cards).
Apple WWDC 2025 məlumatına görə, sabit əyrilər əvəzinə yay animasiyasından istifadə qavranılan gecikməni (perceived latency) 30–50% azaldır, bunun səbəbi başlanğıcda təbii sürətlənmə və sonda rəvan yavaşlamadır. Spring Animation hərəkətlə bağlı istənilən animasiya üçün tövsiyə olunur: yerdəyişmə, miqyaslama, görünmə/gizlənmə.
Yayın davranışı dörd parametrlə müəyyən edilir. Stiffness (sərtlik) — tarazlığa qayıdış qüvvəsi: 100–300 dəyəri siyahılar üçün yumşaq yay, 500–1000 isə düymələr və keçidlər üçün sərt yay verir. Damping (sönümləmə) — hərəkətə müqavimət: 0 — sonsuz rəqslər, 0.1–0.5 — nəzərə çarpan sönümlənən rəqslər (sıçrayış effekti), 1 — kritik sönümləmə (rəqssiz, rəvan yavaşlama).
| Parametr | Diapazon | Effekt | İstifadə nümunəsi |
|---|---|---|---|
| Stiffness | 100–1000 | Tarazlığa qayıdış sürəti | 200 = siyahı, 600 = düymə |
| Damping | 0.0–1.0 | Rəqslərin sönümlənməsi | 0.3 = sıçrayış, 1.0 = rəqssiz |
| Mass | 0.1–10.0 | Obyektin ətaləti | 1.0 = standart, 3.0 = ağır element |
| Initial Velocity | İstənilən | Piksel/san ilə başlanğıc sürət | Drag-to-dismiss zamanı barmaq sürəti |
Kritik sönümləmə (damping = 1.0) — əksər UI animasiyaları üçün optimal rejim: obyekt hədəf vəziyyətinə maksimal sürətlə aşmadan qayıdır. Sıçrayış effekti üçün (məsələn, pull-to-refresh) damping = 0.3–0.5 istifadə edin. Modal pəncərələrin görünməsi üçün — damping = 0.6–0.8, stiffness = 300–500. Kütlə nadir hallarda dəyişdirilir — standart dəyər 1.0 demək olar ki, bütün hallar üçün uyğundur.
iOS-da Spring Animation iOS 7-dən etibarən UIView.animate(withDuration:delay:usingSpringWithDamping:initialSpringVelocity:) və iOS 9-dan CASpringAnimation (Core Animation) vasitəsilə əlçatandır. UIView versiyası View xüsusiyyətlərinin (transform, alpha, center) animasiyası üçün daha sadə və populyardır. CASpringAnimation daha dəqiqdir və stiffness, damping və mass-ə ayrıca xüsusiyyətlər kimi giriş imkanı verir.
import UIKit
// UIView.animate yay parametrləri ilə
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 — parametrlər üzərində dəqiq nəzarət
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 — hesablanmış müddət
spring.duration = spring.settlingDuration
view.layer.add(spring, forKey: "scaleSpring")
CASpringAnimation.settlingDuration — Core Animation-un unikal xüsusiyyətidir, yayın tarazlığa çatması üçün lazım olan minimum animasiya müddətini hesablayır. Bu o deməkdir ki, siz əl ilə duration seçməli deyilsiniz — sistem rəqslərin sönümlənməsinin nə qədər vaxt aparacağını özü müəyyən edir. UIView.animate üçün müddət açıq şəkildə verilir, damping 0.3–0.7 isə nəzərə çarpan sıçrayış effekti verir. UIPanGestureRecognizer ilə əlaqə üçün velocityRecognizer.velocity(in: view) dəyərini initialSpringVelocity kimi ötürün — beləliklə animasiya barmağın hərəkətini eyni sürətlə davam etdirir.
Android-də SpringAnimation AndroidX Dynamic Animation (androidx.dynamicanimation) kitabxanasına daxildir. Əsas sinif — SpringAnimation, View və ya fərdi obyektin istənilən float xüsusiyyətini animasiya edir. Parametrlər SpringForce vasitəsilə təyin edilir — stiffness (standart STIFFNESS_MEDIUM = 600) və dampingRatio (standart DAMPING_RATIO_MEDIUM_BOUNCY = 0.5).
// build.gradle.kts
implementation("androidx.dynamicanimation:dynamicanimation:1.1.0")
// Kotlin: SpringAnimation fərdi SpringForce ilə
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 jestdən başlanğıc sürəti ilə
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) "> İlkin mövqeyə qayıdış
setStartVelocity(velocity)
start()
}
true
}
else -> false
}
}
"> Custom xassə üçün 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 sabitləri: 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 animasiyası olan RecyclerView üçün resursları boşaltmaq üçün DynamicAnimation.OnAnimationEndListener ilə SpringAnimation istifadə edin. Çoxlu xüsusiyyətlərin animasiyası üçün SpringAnimation.createFor(view, property) istifadə edin.
Jetpack Compose: Compose 1.0-dan etibarən, yay animasiyası spring() ilə Animatable vasitəsilə əlçatandır — animationSpec = spring(dampingRatio = 0.5f, stiffness = 300f). Bu, Compose layihələri üçün üstünlük verilən üsuldur, çünki DynamicAnimation-dən SpringAnimation yalnız View sistemi ilə uyğunlaşır. Compose versiyası spring eyni fiziki mühərrikdən istifadə edir, lakin Compose Animation System kontekstində işləyir və detachment zamanı avtomatik dayanır.
Spring Animation və Easing əyriləri (easeInOut, FastOutSlowIn, decelerate) müxtəlif vəzifələri həll edir. Easing əyriləri — sabit vaxtla riyazi olaraq verilmiş trayektoriyadır. Spring — fiziki simulyasiyadır, burada vaxt parametrlərdən və başlanğıc şərtlərdən asılıdır. Sadə görünmə/gizlənmə animasiyaları üçün Easing əyriləri kifayətdir. İstifadəçi hərəkəti ilə bağlı animasiyalar üçün (drag, swipe, scroll) Spring Animation daha təbiidir.
| Ssenari | Tövsiyə | Parametrlər |
|---|---|---|
| Elementin görünməsi | Spring (damping = 0.7, stiffness = 400) | Yüngül aşma ilə rəvan görünmə |
| Swipe-to-dismiss | Spring + başlanğıc sürət | setStartVelocity(velocity), damping = 0.5 |
| İkon animasiyası | Spring (damping = 0.3, stiffness = 600) | Vurğu effektləri üçün nəzərə çarpan sıçrayış |
| Scroll fizikası | Spring (sistem) | Fərdiləşdirməyin — Android özü idarə edir |
| Ölçü dəyişməsi | Easing (FastOutSlowIn) | Layout dəyişiklikləri üçün Easing daha etibarlıdır |
Anti-patterns: layout parametrlərinin (LayoutParams vasitəsilə View-in eni/hündürlüyü) animasiyası üçün Spring Animation istifadə etməyin — bu, hər kadrda iyerarxiyanın yenidən hesablanmasına səbəb olur, titrəmə və FPS düşməsinə gətirib çıxarır. Rəng animasiyası üçün də Easing əyriləri daha yaxşıdır. Scroll mövqeyinin animasiyası üçün sistem Scroller-dən fling ilə istifadə edin — Spring Animation burada üstünlük vermir. Android-də maksimal performans üçün eyni anda aktiv SpringAnimation sayını 10–15 ilə məhdudlaşdırın.
Tez-tez verilən suallar
Stiffness — yayın sərtliyi (qayıdış qüvvəsi). Yüksək dəyər (1000) — sürətli, kəskin hərəkət. Aşağı (100) — yumşaq, yavaş. Damping — sönümləmə (müqavimət). Aşağı (0.2) — sıçrayışla uzun rəqslər. Yüksək (1.0) — rəqssiz, rəvan yavaşlama. Stiffness sürəti, damping isə rəqslərin mövcudluğunu və intensivliyini müəyyən edir.
damping = 0.5 və stiffness = 400 ilə başlayın — bu, iOS və Android üçün universal başlanğıc dəstidir. Elementlərin görünməsi üçün damping-i 0.7-yə qaldırın. Vurğu effektləri üçün (bəyənmə, səbətə əlavə etmə) damping-i 0.3-ə endirin, stiffness = 600. Material Motion üçün damping = 0.6 və stiffness = 300 istifadə edin. Animasiyanı simulyatorda deyil, real cihazda yoxlayın.
Bəli, SwiftUI-da yay animasiyası .animation(.spring(dampingFraction: 0.5, response: 0.5), value: state) və ya .spring(blendDuration: 0.3) ilə withAnimation-də təyin edilir. response və dampingFraction UIKit-dən stiffness və damping-i təkrarlayır. interactiveSpring() üçün .interactiveSpring() istifadə edin — drag animasiyaları üçün optimallaşdırılmış, jestdən başlanğıc sürəti olan xüsusi versiya.
SpringForce.finalPosition-u yoxlayın — əgər təyin olunmayıbsa və ya cari dəyərə bərabərdirsə, animasiya başlaya bilməz. Activity/Fragment-in onPause() metodunda springAnim.cancel() çağırın. RecyclerView-də SpringAnimation üçün view.setOnDetachListener { animator.cancel() } istifadə edin. Jetpack Compose-da SpringAnimation kompozisiya zamanı avtomatik dayanır.
Bəli. iOS-da view.layer.removeAnimation(forKey:) çağırın — animasiya cari kadrda dayanacaq. Android-də springAnim.cancel() çağırın — obyekt cari mövqedə qalacaq. Yeni hədəf dəyərinə rəvan keçid üçün finalPosition-u yeniləyin və cancel çağırmayın — SpringAnimation trayektoriyanı avtomatik yenidən hesablayacaq. Android-də SkipToEnd üçün springAnim.skipToEnd() istifadə edin.
Nəticə
Açar təslim mobil tətbiq hazırlayacağıq
IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.
Həm də oxuyun