Spring Animation — essensen, fjäderfysik i animationer

Författare: IT Sectr Publicerad: 2026-03-01 Lästid: 10 min

Spring Animation — animationsteknik som modellerar en fjäders fysiska beteende: massa, styvhet (stiffness), dämpning (damping) och initialhastighet. Till skillnad från linjär interpolation och Bézierkurvor skapar fjäderanimation en naturlig rörelse med effekt av dämpade svängningar som ser organisk ut på alla enheter. Enligt Material Design Guidelines (2026) används Spring Animation i 73% av de animerade gränssnitten i App Stores topp 100 appar. Läs mer om andra animationstyper i den allmänna animationsguiden.

Huvudpunkter

  • Spring Animation — animation baserad på fjäderns fysiska modell med massa och dämpning.
  • Damping — dämpningskoefficient för svängningar: 0 = oändliga, 1 = utan översläng.
  • Stiffness — fjäderstyvhet: ju högre, desto snabbare återgång till jämvikt.
  • CASpringAnimation — iOS-klass för fjäderanimation av CALayer med durationsberäkning.
  • SpringAnimation — Android-klass från AndroidX Dynamic Animation-biblioteket.

Vad är Spring Animation?

Spring Animation — är en animation vars rörelse beskrivs av ekvationen för en harmonisk oscillator med dämpning. Istället för att interpolera värdet från 0 till 1 under en fast tid beräknar Spring Animation objektets position vid varje ögonblick baserat på fysikaliska parametrar: massa (mass), styvhet (stiffness), dämpning (damping) och initialhastighet (initialVelocity). Resultatet — en naturlig, organisk rörelse som inte ser 'mekanisk' ut.

Till skillnad från Easing-kurvor (easeIn, easeOut, cubic-bezier), där durationen är fast och banan förutbestämd, anpassar sig Spring Animation dynamiskt: om du ändrar målvärdet under animationen, omberäknar fjädern smidigt banan från den aktuella positionen. Detta är särskilt viktigt för animationer som kan avbrytas — drag-to-dismiss, pull-to-refresh, svepbara kort (swipeable cards).

Enligt Apple WWDC 2025 minskar användningen av fjäderanimation istället för fasta kurvor den upplevda latensen (perceived latency) med 30–50% tack vare naturlig acceleration i början och mjuk inbromsning i slutet. Spring Animation rekommenderas för alla rörelserelaterade animationer: förflyttning, skalning, visning/döljning.

Fjäderns fysikaliska parametrar: damping och stiffness

Fjäderns beteende bestäms av fyra parametrar. Stiffness (styvhet) — återgångskraften till jämvikt: värde 100–300 ger en mjuk fjäder för listor, 500–1000 — en hård fjäder för knappar och omkopplare. Damping (dämpning) — motstånd mot rörelse: 0 — oändliga svängningar, 0.1–0.5 — märkbara dämpade svängningar (studseffekt), 1 — kritisk dämpning (utan svängningar, mjuk inbromsning).

ParameterIntervallEffektAnvändningsexempel
Stiffness100–1000Hastighet för återgång till jämvikt200 = lista, 600 = knapp
Damping0.0–1.0Dämpning av svängningar0.3 = studs, 1.0 = utan svängningar
Mass0.1–10.0Objektets tröghet1.0 = standard, 3.0 = tungt element
Initial VelocityValfrittInitialhastighet i pixlar/sFingerhastighet vid drag-to-dismiss

Kritisk dämpning (damping = 1.0) — optimalt läge för de flesta UI-animationer: objektet återgår till målpositionen så snabbt som möjligt utan översläng. För studseffekt (t.ex. pull-to-refresh) använd damping = 0.3–0.5. För visning av modalafönster — damping = 0.6–0.8 med stiffness = 300–500. Massa ändras sällan — standardvärdet 1.0 passar nästan alla fall.

Spring Animation i iOS (Swift)

På iOS är Spring Animation tillgänglig via UIView.animate(withDuration:delay:usingSpringWithDamping:initialSpringVelocity:) från iOS 7 och CASpringAnimation (Core Animation) från iOS 9. UIView-versionen är enklare och populärare för animering av View-egenskaper (transform, alpha, center). CASpringAnimation är mer exakt och ger tillgång till stiffness, damping och mass som separata egenskaper.

swift
import UIKit

// UIView.animate med fjäderparametrar
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 — exakt kontroll över parametrar
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 — beräknad varaktighet
spring.duration = spring.settlingDuration
view.layer.add(spring, forKey: "scaleSpring")

CASpringAnimation.settlingDuration — en unik egenskap hos Core Animation som beräknar den minsta animationsduration som krävs för att fjädern ska nå jämvikt. Detta innebär att du inte behöver välja duration manuellt — systemet bestämmer själv hur lång tid dämpningen av svängningarna tar. För UIView.animate anges duration explicit och damping 0.3–0.7 ger en märkbar studseffekt. För koppling med UIPanGestureRecognizer, skicka velocityRecognizer.velocity(in: view) som initialSpringVelocity — på så sätt fortsätter animationen fingrets rörelse med samma hastighet.

Spring Animation i Android (Kotlin)

På Android ingår SpringAnimation i AndroidX Dynamic Animation-biblioteket (androidx.dynamicanimation). Huvudklassen — SpringAnimation, som animerar vilken float-egenskap som helst hos en View eller ett anpassat objekt. Parametrar ställs in via SpringForce — stiffness (standard STIFFNESS_MEDIUM = 600) och dampingRatio (standard DAMPING_RATIO_MEDIUM_BOUNCY = 0.5).

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

// Kotlin: SpringAnimation med anpassad 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 med initialhastighet från gest
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) "> Återgå till utgångsposition
                setStartVelocity(velocity)
                start()
            }
            true
        }
        else -> false
    }
}

"> SpringAnimation för anpassad egenskap
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-konstanter: 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). För RecyclerView med elementanimation, använd SpringAnimation med DynamicAnimation.OnAnimationEndListener för att frigöra resurser. För animering av flera egenskaper, använd SpringAnimation.createFor(view, property).

Jetpack Compose: från Compose 1.0 är fjäderanimation tillgänglig via Animatable med spring() — animationSpec = spring(dampingRatio = 0.5f, stiffness = 300f). Detta är den föredragna metoden för Compose-projekt, eftersom SpringAnimation från DynamicAnimation endast är kompatibel med View-systemet. Compose-versionen spring använder samma fysikmotor, men fungerar i Compose Animation Systems sammanhang och pausar automatiskt vid detachment.

Spring Animation vs Easing: när man ska välja vad

Spring Animation och Easing-kurvor (easeInOut, FastOutSlowIn, decelerate) löser olika uppgifter. Easing-kurvor — en matematiskt definierad bana med fast tid. Spring — fysisk simulering, där tiden beror på parametrar och initiala villkor. För enkla visnings-/dölj-animationer räcker Easing-kurvor. För användarrörelserelaterade animationer (drag, swipe, scroll) ger Spring Animation en mer naturlig återkoppling.

ScenarioRekommendationParametrar
Element visasSpring (damping = 0.7, stiffness = 400)Mjuk visning med lätt översläng
Swipe-to-dismissSpring + initialhastighetsetStartVelocity(velocity), damping = 0.5
IkonanimationSpring (damping = 0.3, stiffness = 600)Märkbar studs för accenteffekter
Scroll-fysikSpring (system)Anpassa inte — Android hanterar själv
StorleksändringEasing (FastOutSlowIn)Easing är mer pålitlig för layoutändringar

Anti-patterns: använd inte Spring Animation för animering av layoutparametrar (bredd/höjd på View via LayoutParams) — detta orsakar omberäkning av hierarkin i varje bildruta, vilket leder till skakningar och FPS-fall. För färganimation är Easing-kurvor också bättre. För animering av scrollposition, använd systemets Scroller med fling — Spring Animation ger inga fördelar här. För maximal prestanda på Android, begränsa antalet samtidigt aktiva SpringAnimation till 10–15.

Vanliga frågor

Vad är skillnaden mellan damping och stiffness?

Stiffness — fjäderns styvhet (återgångskraft). Högt värde (1000) — snabb, abrupt rörelse. Lågt (100) — mjuk, långsam. Damping — dämpning (motstånd). Låg (0.2) — långa svängningar med studs. Hög (1.0) — utan svängningar, mjuk inbromsning. Stiffness bestämmer hastigheten, damping — förekomsten och intensiteten av svängningar.

Hur väljer man rätt parametrar för Spring Animation?

Börja med damping = 0.5 och stiffness = 400 — detta är en universell startuppsättning för iOS och Android. För visning av element, öka damping till 0.7. För accenteffekter (gilla, lägg i kundvagn), minska damping till 0.3 med stiffness = 600. För Material Motion, använd damping = 0.6 och stiffness = 300. Kontrollera animationen på en verklig enhet, inte i simulatorn.

Fungerar Spring Animation i SwiftUI?

Ja, i SwiftUI ställs fjäderanimation in via .animation(.spring(dampingFraction: 0.5, response: 0.5), value: state) eller .spring(blendDuration: 0.3) i withAnimation. response och dampingFraction motsvarar stiffness och damping från UIKit. För interactiveSpring() använd .interactiveSpring() — en specialversion med initialhastighet från gesten, optimerad för drag-animationer.

Varför stannar inte Spring Animation på Android?

Kontrollera SpringForce.finalPosition — om den inte är inställd eller är lika med det aktuella värdet kan animationen inte starta. Anropa springAnim.cancel() i onPause() för Activity/Fragment. För SpringAnimation i RecyclerView, använd view.setOnDetachListener { animator.cancel() }. För Jetpack Compose pausar SpringAnimation automatiskt vid komposition.

Kan Spring Animation avbrytas smidigt?

Ja. På iOS, anropa view.layer.removeAnimation(forKey:) — animationen stannar vid den aktuella bildrutan. På Android, anropa springAnim.cancel() — objektet stannar på den aktuella positionen. För en smidig övergång till ett nytt målvärde, uppdatera finalPosition och anropa inte cancel — SpringAnimation omberäknar automatiskt banan. För SkipToEnd, använd springAnim.skipToEnd() på Android.

Sammanfattning

  • Spring Animation — animation baserad på fjäderns fysiska modell med parametrarna stiffness och damping.
  • Damping — dämpningskoefficient (0 = oändliga svängningar, 1 = kritisk dämpning).
  • Stiffness — fjäderstyvhet: 200 (soft), 600 (medium), 1800 (high) på Android.
  • iOS: UIView.animate med usingSpringWithDamping (UIKit) eller CASpringAnimation (Core Animation).
  • Android: SpringAnimation + SpringForce från AndroidX Dynamic Animation.
  • Jetpack Compose: animationSpec = spring(dampingRatio, stiffness) via Animatable.
  • Spring Animation är att föredra framför Easing för gestbaserade animationer (swipe, drag, pull-to-refresh).

Vi utvecklar en mobil applikation nyckelfärdigt

IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.

Diskutera projektet

Läs också