Spring Animation, bir yayın fiziksel davranışını simüle eden bir animasyon tekniğidir: kütle, sertlik (stiffness), sönümleme (damping) ve başlangıç hızı. Doğrusal enterpolasyonlar ve Bezier eğrilerinin aksine, yay animasyonu sönümlü salınım etkisiyle doğal bir hareket oluşturur ve her cihazda organik görünür. Material Design Guidelines'a (2026) göre, Spring Animation, App Store'daki ilk 100 uygulamanın %73'ünde animasyonlu arayüzlerde kullanılmaktadır. Diğer animasyon türleri hakkında daha fazla bilgi için genel animasyon rehberine bakın.
Önemli Noktalar
Spring Animation, hareketi sönümlü harmonik osilatör denklemi ile tanımlanan bir animasyondur. Sabit bir sürede 0'dan 1'e bir değer enterpole etmek yerine, Spring Animation fiziksel parametrelere (kütle, sertlik, sönümleme ve başlangıç hızı) dayalı olarak her andaki nesne konumunu hesaplar. Sonuç, "mekanik" görünmeyen doğal, organik bir harekettir.
Sürenin sabit olduğu ve yörüngenin önceden belirlendiği Easing eğrilerinin (easeIn, easeOut, cubic-bezier) aksine, Spring Animation dinamik olarak uyum sağlar: animasyon sırasında hedef değer değişirse, yay mevcut konumdan itibaren yörüngeyi yumuşak bir şekilde yeniden hesaplar. Bu, kesintiye uğrayabilecek animasyonlar için özellikle önemlidir — sürükle-kapat, çek-yenile, kaydırılabilir kartlar.
Apple WWDC 2025'e göre, sabit eğriler yerine yay animasyonu kullanmak, başlangıçtaki doğal hızlanma ve sondaki yumuşak yavaşlama sayesinde algılanan gecikmeyi %30–50 oranında azaltır. Spring Animation, hareketle ilgili her türlü animasyon için önerilir: taşıma, ölçekleme, görünme/kaybolma.
Yayın davranışı dört parametreyle tanımlanır. Stiffness (sertlik), dengeye döndürme kuvvetidir: 100–300 değeri listeler için yumuşak bir yay verir, 500–1000 düğmeler ve anahtarlar için sert bir yay verir. Damping (sönümleme), harekete karşı dirençtir: 0 — sonsuz salınım, 0.1–0.5 — belirgin sönümlü salınım (sekme efekti), 1 — kritik sönümleme (salınımsız, yumuşak yavaşlama).
| Parametre | Aralık | Etki | Kullanım örneği |
|---|---|---|---|
| Stiffness | 100–1000 | Dengeye dönüş hızı | 200 = liste, 600 = düğme |
| Damping | 0.0–1.0 | Salınım sönümleme | 0.3 = sekme, 1.0 = salınım yok |
| Mass | 0.1–10.0 | Nesne ataleti | 1.0 = standart, 3.0 = ağır öğe |
| Initial Velocity | Herhangi | Piksel/s cinsinden başlangıç hızı | Sürükle-kapat sırasında parmak hızı |
Kritik sönümleme (damping = 1.0), çoğu UI animasyonu için en uygun moddur: nesne, aşım olmadan mümkün olduğunca hızlı bir şekilde hedef konuma döner. Sekme efekti için (örneğin, çek-yenile), damping = 0.3–0.5 kullanın. Modal pencere görünümü için — stiffness = 300–500 ile damping = 0.6–0.8 kullanın. Kütle nadiren değiştirilir — standart değer 1.0 hemen hemen tüm durumlar için uygundur.
iOS'ta Spring Animation, iOS 7'den itibaren UIView.animate(withDuration:delay:usingSpringWithDamping:initialSpringVelocity:) ve iOS 9'dan itibaren CASpringAnimation (Core Animation) aracılığıyla kullanılabilir. UIView sürümü, View özelliklerini (transform, alpha, center) canlandırmak için daha basit ve popülerdir. CASpringAnimation daha hassastır ve stiffness, damping ve mass'e ayrı özellikler olarak erişim sağlar.
import UIKit
// UIView.animate yay parametreleriyle
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 — parametreler üzerinde hassas kontrol
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 — hesaplanan süre
spring.duration = spring.settlingDuration
view.layer.add(spring, forKey: "scaleSpring")
CASpringAnimation.settlingDuration, yayın dengeye ulaşması için gereken minimum animasyon süresini hesaplayan benzersiz bir Core Animation özelliğidir. Bu, süreyi manuel olarak seçmeniz gerekmediği anlamına gelir — sistem, salınım sönümlemesinin ne kadar süreceğini kendisi belirler. UIView.animate için süre açıkça belirlenir ve 0.3–0.7'lik damping belirgin bir sekme efekti verir. UIPanGestureRecognizer ile entegrasyon için, velocityRecognizer.velocity(in: view)'i initialSpringVelocity olarak iletin — böylece animasyon parmak hareketine aynı hızda devam eder.
Android'de SpringAnimation, AndroidX Dynamic Animation kitaplığının (androidx.dynamicanimation) bir parçasıdır. Ana sınıf SpringAnimation'dir ve bir View veya özel nesnenin herhangi bir float özelliğini canlandırır. Parametreler SpringForce aracılığıyla ayarlanır — stiffness (varsayılan STIFFNESS_MEDIUM = 600) ve dampingRatio (varsayılan DAMPING_RATIO_MEDIUM_BOUNCY = 0.5).
// build.gradle.kts
implementation("androidx.dynamicanimation:dynamicanimation:1.1.0")
// Kotlin: Özel SpringForce ile SpringAnimation
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()
}
// Jestden başlangıç hızı ile SpringAnimation
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) "> Başlangıç konumuna dönüş
setStartVelocity(velocity)
start()
}
true
}
else -> false
}
}
"> Özel özellik için 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 sabitleri: 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). Öğe animasyonlu RecyclerView için, kaynakları serbest bırakmak üzere DynamicAnimation.OnAnimationEndListener ile SpringAnimation kullanın. Birden çok özelliği canlandırmak için SpringAnimation.createFor(view, property) kullanın.
Jetpack Compose: Compose 1.0'dan itibaren, yay animasyonu spring() ile Animatable aracılığıyla kullanılabilir — animationSpec = spring(dampingRatio = 0.5f, stiffness = 300f). Bu, Compose projeleri için tercih edilen yaklaşımdır çünkü DynamicAnimation'daki SpringAnimation yalnızca View sistemiyle uyumludur. spring'in Compose sürümü aynı fizik motorunu kullanır ancak Compose Animation System bağlamında çalışır ve ayrılma durumunda otomatik olarak duraklatılır.
Spring Animation ve Easing eğrileri (easeInOut, FastOutSlowIn, decelerate) farklı sorunları çözer. Easing eğrileri, sabit süreli matematiksel olarak tanımlanmış yörüngelerdir. Spring, sürenin parametrelere ve başlangıç koşullarına bağlı olduğu fiziksel bir simülasyondur. Basit görünme/kaybolma animasyonları için Easing eğrileri yeterlidir. Kullanıcı hareketiyle (sürükleme, kaydırma, scrol) bağlantılı animasyonlar için Spring Animation daha doğal bir yanıt sağlar.
| Senaryo | Öneri | Parametreler |
|---|---|---|
| Öğe görünümü | Spring (damping = 0.7, stiffness = 400) | Hafif aşımla yumuşak görünüm |
| Kaydırarak kapatma | Spring + başlangıç hızı | setStartVelocity(velocity), damping = 0.5 |
| Simgeler için animasyon | Spring (damping = 0.3, stiffness = 600) | Vurgu efektleri için belirgin sekme |
| Scroll fiziği | Spring (sistem) | Özelleştirmeyin — Android yönetir |
| Boyut değişikliği | Easing (FastOutSlowIn) | Layout değişiklikleri için Easing daha güvenilir |
Anti-pattern'ler: layout parametrelerini (LayoutParams aracılığıyla View genişliği/yüksekliği) canlandırmak için Spring Animation kullanmayın — bu, her karede hiyerarşi yeniden hesaplamasına neden olarak takılmalara ve FPS düşüşlerine yol açar. Renk animasyonu için de Easing eğrileri tercih edilir. Scroll konumu animasyonu için, fling ile sistem Scroller'ını kullanın — Spring Animation burada avantaj sağlamaz. Android'de maksimum performans için aynı anda aktif SpringAnimation örneklerinin sayısını 10–15 ile sınırlayın.
Sıkça Sorulan Sorular
Stiffness yayın sertliğidir (geri çağırma kuvveti). Yüksek değer (1000) hızlı, keskin hareket üretir. Düşük değer (100) yumuşak, yavaş hareket üretir. Damping harekete karşı dirençtir. Düşük değer (0.2) sekmeli uzun salınımlar üretir. Yüksek değer (1.0) salınımsız, yumuşak yavaşlama üretir. Stiffness hızı belirler, damping salınımların varlığını ve yoğunluğunu belirler.
damping = 0.5 ve stiffness = 400 ile başlayın — bu, iOS ve Android için evrensel bir başlangıç setidir. Öğe görünümü için damping'i 0.7'ye yükseltin. Vurgu efektleri (beğeni, sepete ekleme) için damping'i 0.3'e düşürün ve stiffness = 600 yapın. Material Motion için damping = 0.6 ve stiffness = 300 kullanın. Animasyonu simülatörde değil, gerçek bir cihazda test edin.
Evet, SwiftUI'de yay animasyonu .animation(.spring(dampingFraction: 0.5, response: 0.5), value: state) veya withAnimation içinde .spring(blendDuration: 0.3) ile ayarlanır. response ve dampingFraction, UIKit'teki stiffness ve damping'i yansıtır. İnteraktif sürükleme animasyonları için .interactiveSpring() kullanın — sürükleme animasyonları için optimize edilmiş, jest tabanlı başlangıç hızına sahip özel bir sürüm.
SpringForce.finalPosition kontrol edin — ayarlanmamışsa veya mevcut değere eşitse, animasyon başlamayabilir. Activity/Fragment'in onPause() yönteminde springAnim.cancel() çağırın. RecyclerView'daki SpringAnimation için view.setOnDetachListener { animator.cancel() } kullanın. Jetpack Compose için SpringAnimation, kompozisyon değişikliklerinde otomatik olarak duraklatılır.
Evet. iOS'ta view.layer.removeAnimation(forKey:) çağırın — animasyon mevcut karede durur. Android'de springAnim.cancel() çağırın — nesne mevcut konumunda kalır. Yeni bir hedef değere yumuşak geçiş için finalPosition'ı güncelleyin ve cancel çağırmayın — SpringAnimation yörüngeyi otomatik olarak yeniden hesaplar. SkipToEnd için Android'de springAnim.skipToEnd() kullanın.
Özet
Anahtar teslim bir mobil uygulama geliştireceğiz
IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.
Ayrıca okuyun