Spring Animation — podstata, fyzika pružiny v animacích

Autor: IT Sectr Publikováno: 2026-03-01 Doba čtení: 10 min

Spring Animation — technika animace modelující fyzikální chování pružiny: hmotnost, tuhost (stiffness), tlumení (damping) a počáteční rychlost. Na rozdíl od lineárních interpolací a Bézierových křivek vytváří pružinová animace přirozený pohyb s efektem tlumených kmitů, který vypadá organicky na všech zařízeních. Podle Material Design Guidelines (2026) se Spring Animation používá v 73% animovaných rozhraní top 100 aplikací App Store. Více o dalších typech animací si přečtěte v obecném průvodci animacemi.

Hlavní body

  • Spring Animation — animace založená na fyzikálním modelu pružiny s hmotností a tlumením.
  • Damping — koeficient tlumení kmitů: 0 = nekonečné, 1 = bez překmitu.
  • Stiffness — tuhost pružiny: čím vyšší, tím rychlejší návrat do rovnováhy.
  • CASpringAnimation — iOS třída pro pružinovou animaci CALayer s výpočtem doby trvání.
  • SpringAnimation — Android třída z knihovny AndroidX Dynamic Animation.

Co je Spring Animation?

Spring Animation — je animace, jejíž pohyb je popsán rovnicí harmonického oscilátoru s tlumením. Namísto interpolace hodnoty z 0 na 1 v pevném čase Spring Animation vypočítává polohu objektu v každém okamžiku na základě fyzikálních parametrů: hmotnost (mass), tuhost (stiffness), tlumení (damping) a počáteční rychlost (initialVelocity). Výsledkem je přirozený, organický pohyb, který nevypadá „mechanicky”.

Na rozdíl od Easing křivek (easeIn, easeOut, cubic-bezier), kde je doba trvání pevná a trajektorie předem daná, se Spring Animation dynamicky přizpůsobuje: pokud během animace změníte cílovou hodnotu, pružina plynule přepočítá trajektorii z aktuální polohy. To je obzvláště důležité pro animace, které mohou být přerušeny — drag-to-dismiss, pull-to-refresh, posuvné karty (swipeable cards).

Podle Apple WWDC 2025 snižuje použití pružinové animace namísto pevných křivek vnímanou latenci (perceived latency) o 30–50% díky přirozenému zrychlení na začátku a plynulému zpomalení na konci. Spring Animation se doporučuje pro všechny animace související s pohybem: posun, škálování, zobrazení/skrytí.

Fyzikální parametry pružiny: damping a stiffness

Chování pružiny určují čtyři parametry. Stiffness (tuhost) — síla návratu do rovnováhy: hodnota 100–300 dává měkkou pružinu pro seznamy, 500–1000 — tvrdou pro tlačítka a přepínače. Damping (tlumení) — odpor proti pohybu: 0 — nekonečné kmity, 0.1–0.5 — znatelné tlumené kmity (efekt odrazu), 1 — kritické tlumení (bez kmitů, plynulé zpomalení).

ParametrRozsahEfektPříklad použití
Stiffness100–1000Rychlost návratu do rovnováhy200 = seznam, 600 = tlačítko
Damping0.0–1.0Tlumení kmitů0.3 = odraz, 1.0 = bez kmitů
Mass0.1–10.0Setrvačnost objektu1.0 = standard, 3.0 = těžký prvek
Initial VelocityLibovolnýPočáteční rychlost v px/sRychlost prstu při drag-to-dismiss

Kritické tlumení (damping = 1.0) — optimální režim pro většinu UI animací: objekt se vrací do cílové polohy maximálně rychle bez překmitu. Pro efekt odrazu (např. pull-to-refresh) použijte damping = 0.3–0.5. Pro zobrazení modálních oken — damping = 0.6–0.8 s stiffness = 300–500. Hmotnost se mění zřídka — standardní hodnota 1.0 vyhovuje téměř všem případům.

Spring Animation v iOS (Swift)

V iOS je Spring Animation k dispozici prostřednictvím UIView.animate(withDuration:delay:usingSpringWithDamping:initialSpringVelocity:) od iOS 7 a CASpringAnimation (Core Animation) od iOS 9. Verze UIView je jednodušší a oblíbenější pro animaci vlastností View (transform, alpha, center). CASpringAnimation je přesnější a poskytuje přístup k stiffness, damping a mass jako samostatným vlastnostem.

swift
import UIKit

// UIView.animate s pružinovými parametry
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 — přesná kontrola parametrů
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 — vypočítaná doba trvání
spring.duration = spring.settlingDuration
view.layer.add(spring, forKey: "scaleSpring")

CASpringAnimation.settlingDuration — jedinečná vlastnost Core Animation, která vypočítává minimální dobu trvání animace potřebnou k dosažení rovnováhy pružiny. To znamená, že nemusíte ručně volit duration — systém sám určí, jak dlouho bude tlumení kmitů trvat. U UIView.animate se doba trvání zadává explicitně a damping 0.3–0.7 poskytuje znatelný efekt odrazu. Pro propojení s UIPanGestureRecognizer předejte velocityRecognizer.velocity(in: view) jako initialSpringVelocity — animace tak bude pokračovat v pohybu prstu stejnou rychlostí.

Spring Animation v Android (Kotlin)

V Android je SpringAnimation součástí knihovny AndroidX Dynamic Animation (androidx.dynamicanimation). Hlavní třída — SpringAnimation, která animuje libovolnou float vlastnost View nebo vlastního objektu. Parametry se nastavují prostřednictvím SpringForce — stiffness (výchozí STIFFNESS_MEDIUM = 600) a dampingRatio (výchozí DAMPING_RATIO_MEDIUM_BOUNCY = 0.5).

kotlin
// build.gradle.kts
implementation("androidx.dynamicanimation:dynamicanimation:1.1.0")

// Kotlin: SpringAnimation s vlastním SpringForce
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 s počáteční rychlostí z gesta
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) "> Návrat do výchozí polohy
                setStartVelocity(velocity)
                start()
            }
            true
        }
        else -> false
    }
}

"> SpringAnimation pro vlastní vlastnost
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() }

Konstanty SpringForce: 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). Pro RecyclerView s animací prvků použijte SpringAnimation s DynamicAnimation.OnAnimationEndListener pro uvolnění zdrojů. Pro animaci více vlastností použijte SpringAnimation.createFor(view, property).

Jetpack Compose: od Compose 1.0 je pružinová animace k dispozici prostřednictvím Animatable s spring() — animationSpec = spring(dampingRatio = 0.5f, stiffness = 300f). Toto je preferovaný způsob pro Compose projekty, protože SpringAnimation z DynamicAnimation je kompatibilní pouze se systémem View. Verze Compose spring používá stejný fyzikální engine, ale pracuje v kontextu Compose Animation System a automaticky se pozastavuje při detachmentu.

Spring Animation vs Easing: kdy co zvolit

Spring Animation a Easing křivky (easeInOut, FastOutSlowIn, decelerate) řeší různé úkoly. Easing křivky — matematicky daná trajektorie s pevným časem. Spring — fyzikální simulace, kde čas závisí na parametrech a počátečních podmínkách. Pro jednoduché animace zobrazení/skrytí Easing křivky stačí. Pro animace související s pohybem uživatele (drag, swipe, scroll) poskytuje Spring Animation přirozenější odezvu.

ScénářDoporučeníParametry
Zobrazení prvkuSpring (damping = 0.7, stiffness = 400)Plynulé zobrazení s mírným překmitem
Swipe-to-dismissSpring + počáteční rychlostsetStartVelocity(velocity), damping = 0.5
Animace ikonySpring (damping = 0.3, stiffness = 600)Znatelný odraz pro akcentní efekty
Fyzika scrollSpring (systémová)Nepřizpůsobovat — Android spravuje sám
Změna velikostiEasing (FastOutSlowIn)Easing je spolehlivější pro změny layoutu

Anti-patterns: nepoužívejte Spring Animation pro animaci parametrů layoutu (šířka/výška View přes LayoutParams) — to způsobuje přepočet hierarchie v každém snímku, což vede k cukání a poklesu FPS. Pro animaci barvy jsou také lepší Easing křivky. Pro animaci pozice scroll použijte systémový Scroller s fling — Spring Animation zde nenabízí výhody. Pro maximální výkon na Androidu omezte počet současně aktivních SpringAnimation na 10–15.

Často kladené otázky

Jaký je rozdíl mezi damping a stiffness?

Stiffness — tuhost pružiny (síla návratu). Vysoká hodnota (1000) — rychlý, prudký pohyb. Nízká (100) — jemný, pomalý. Damping — tlumení (odpor). Nízké (0.2) — dlouhé kmity s odrazem. Vysoké (1.0) — bez kmitů, plynulé zpomalení. Stiffness určuje rychlost, damping — přítomnost a intenzitu kmitů.

Jak zvolit správné parametry Spring Animation?

Začněte s damping = 0.5 a stiffness = 400 — to je univerzální startovací sada pro iOS a Android. Pro zobrazení prvků zvyšte damping na 0.7. Pro akcentní efekty (like, přidání do košíku) snižte damping na 0.3 s stiffness = 600. Pro Material Motion použijte damping = 0.6 a stiffness = 300. Animaci kontrolujte na reálném zařízení, ne v simulátoru.

Funguje Spring Animation ve SwiftUI?

Ano, ve SwiftUI se pružinová animace nastavuje pomocí .animation(.spring(dampingFraction: 0.5, response: 0.5), value: state) nebo .spring(blendDuration: 0.3) v withAnimation. response a dampingFraction odpovídají stiffness a damping z UIKit. Pro interactiveSpring() použijte .interactiveSpring() — speciální verze s počáteční rychlostí z gesta, optimalizovaná pro drag animace.

Proč Spring Animation na Androidu nezastavuje?

Zkontrolujte SpringForce.finalPosition — pokud není nastavena nebo se rovná aktuální hodnotě, animace nemusí začít. Volejte springAnim.cancel() v onPause() Activity/Fragment. Pro SpringAnimation v RecyclerView použijte view.setOnDetachListener { animator.cancel() }. Pro Jetpack Compose se SpringAnimation automaticky pozastaví při kompozici.

Lze Spring Animation plynule přerušit?

Ano. Na iOS zavolejte view.layer.removeAnimation(forKey:) — animace se zastaví na aktuálním snímku. Na Androidu zavolejte springAnim.cancel() — objekt zůstane na aktuální pozici. Pro plynulý přechod na novou cílovou hodnotu aktualizujte finalPosition a nevolejte cancel — SpringAnimation automaticky přepočítá trajektorii. Pro SkipToEnd použijte springAnim.skipToEnd() na Androidu.

Shrnutí

  • Spring Animation — animace založená na fyzikálním modelu pružiny s parametry stiffness a damping.
  • Damping — koeficient tlumení (0 = nekonečné kmity, 1 = kritické tlumení).
  • Stiffness — tuhost pružiny: 200 (soft), 600 (medium), 1800 (high) na Androidu.
  • iOS: UIView.animate s usingSpringWithDamping (UIKit) nebo CASpringAnimation (Core Animation).
  • Android: SpringAnimation + SpringForce z AndroidX Dynamic Animation.
  • Jetpack Compose: animationSpec = spring(dampingRatio, stiffness) přes Animatable.
  • Spring Animation je preferována před Easingem pro animace s gesty (swipe, drag, pull-to-refresh).

Vyvineme mobilní aplikaci na klíč

IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.

Prodiskutovat projekt

Přečtěte si také