Spring Animation — la physique du ressort dans les animations

Auteur : IT Sectr Publié le : 2026-03-01 Temps de lecture : 10 min

Spring Animation est une technique d'animation qui simule le comportement physique d'un ressort : masse, raideur (stiffness), amortissement (damping) et vitesse initiale. Contrairement aux interpolations linéaires et aux courbes de Bézier, l'animation à ressort crée un mouvement naturel avec un effet d'oscillation amortie qui semble organique sur n'importe quel appareil. Selon les Material Design Guidelines (2026), Spring Animation est utilisée dans 73% des interfaces animées des 100 meilleures applications de l'App Store. En savoir plus sur les autres types d'animation dans le guide général d'animation.

Points clés

  • Spring Animation — animation basée sur un modèle physique de ressort avec masse et amortissement.
  • Damping — coefficient d'amortissement des oscillations : 0 = infinies, 1 = sans dépassement.
  • Stiffness — raideur du ressort : plus la valeur est élevée, plus le retour à l'équilibre est rapide.
  • CASpringAnimation — classe iOS pour l'animation à ressort de CALayer avec calcul de durée.
  • SpringAnimation — classe Android de la bibliothèque AndroidX Dynamic Animation.

Qu'est-ce que Spring Animation ?

Spring Animation est une animation dont le mouvement est décrit par l'équation de l'oscillateur harmonique amorti. Au lieu d'interpoler une valeur de 0 à 1 pendant un temps fixe, Spring Animation calcule la position de l'objet à chaque instant en fonction de paramètres physiques : masse, raideur, amortissement et vitesse initiale. Le résultat est un mouvement naturel et organique qui ne semble pas « mécanique ».

Contrairement aux courbes Easing (easeIn, easeOut, cubic-bezier), où la durée est fixe et la trajectoire prédéterminée, Spring Animation s'adapte dynamiquement : si la valeur cible change pendant l'animation, le ressort recalcule en douceur la trajectoire à partir de la position actuelle. Ceci est particulièrement important pour les animations qui peuvent être interrompues — drag-to-dismiss, pull-to-refresh, cartes glissables (swipeable cards).

Selon Apple WWDC 2025, l'utilisation de l'animation à ressort au lieu de courbes fixes réduit la latence perçue de 30 à 50 % grâce à l'accélération naturelle au début et à la décélération douce à la fin. Spring Animation est recommandée pour toute animation liée au mouvement : déplacement, mise à l'échelle, apparition/disparition.

Paramètres physiques du ressort : damping et stiffness

Le comportement du ressort est défini par quatre paramètres. Stiffness (raideur) est la force de rappel vers l'équilibre : une valeur de 100–300 donne un ressort souple pour les listes, 500–1000 donne un ressort rigide pour les boutons et interrupteurs. Damping (amortissement) est la résistance au mouvement : 0 — oscillations infinies, 0.1–0.5 — oscillations amorties notables (effet de rebond), 1 — amortissement critique (sans oscillations, décélération douce).

ParamètrePlageEffetExemple d'utilisation
Stiffness100–1000Vitesse de retour à l'équilibre200 = liste, 600 = bouton
Damping0.0–1.0Amortissement des oscillations0.3 = rebond, 1.0 = sans oscillations
Mass0.1–10.0Inertie de l'objet1.0 = standard, 3.0 = élément lourd
Initial VelocityQuelconqueVitesse initiale en pixels/sVitesse du doigt lors du drag-to-dismiss

Amortissement critique (damping = 1.0) est le mode optimal pour la plupart des animations d'interface : l'objet retourne à la position cible aussi rapidement que possible sans dépassement. Pour l'effet de rebond (par exemple, pull-to-refresh), utilisez damping = 0.3–0.5. Pour l'apparition de fenêtres modales — damping = 0.6–0.8 avec stiffness = 300–500. La masse est rarement modifiée — la valeur standard de 1.0 convient à presque tous les cas.

Spring Animation sur iOS (Swift)

Sur iOS, Spring Animation est disponible via UIView.animate(withDuration:delay:usingSpringWithDamping:initialSpringVelocity:) depuis iOS 7 et CASpringAnimation (Core Animation) depuis iOS 9. La version UIView est plus simple et plus populaire pour animer les propriétés de View (transform, alpha, center). CASpringAnimation est plus précise et donne accès à stiffness, damping et mass en tant que propriétés séparées.

swift
import UIKit

// UIView.animate avec paramètres de ressort
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 — contrôle précis des paramètres
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 — durée calculée
spring.duration = spring.settlingDuration
view.layer.add(spring, forKey: "scaleSpring")

CASpringAnimation.settlingDuration est une propriété unique de Core Animation qui calcule la durée minimale d'animation nécessaire pour que le ressort atteigne l'équilibre. Cela signifie que vous n'avez pas besoin de choisir la durée manuellement — le système détermine lui-même le temps nécessaire à l'amortissement des oscillations. Pour UIView.animate, la durée est définie explicitement, et un damping de 0.3–0.7 produit un effet de rebond notable. Pour l'intégration avec UIPanGestureRecognizer, passez velocityRecognizer.velocity(in: view) comme initialSpringVelocity — ainsi l'animation continue le mouvement du doigt à la même vitesse.

Spring Animation sur Android (Kotlin)

Sur Android, SpringAnimation fait partie de la bibliothèque AndroidX Dynamic Animation (androidx.dynamicanimation). La classe principale est SpringAnimation, qui anime toute propriété float d'une View ou d'un objet personnalisé. Les paramètres sont définis via SpringForce — stiffness (par défaut STIFFNESS_MEDIUM = 600) et dampingRatio (par défaut DAMPING_RATIO_MEDIUM_BOUNCY = 0.5).

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

// Kotlin : SpringAnimation avec SpringForce personnalisé
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 avec vitesse initiale depuis le geste
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) "> Retour à la position d'origine
                setStartVelocity(velocity)
                start()
            }
            true
        }
        else -> false
    }
}

"> SpringAnimation pour une propriété personnalisée
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() }

Constantes 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). Pour RecyclerView avec animation d'éléments, utilisez SpringAnimation avec DynamicAnimation.OnAnimationEndListener pour libérer les ressources. Pour animer plusieurs propriétés, utilisez SpringAnimation.createFor(view, property).

Jetpack Compose : à partir de Compose 1.0, l'animation à ressort est disponible via Animatable avec spring() — animationSpec = spring(dampingRatio = 0.5f, stiffness = 300f). C'est l'approche préférée pour les projets Compose, car SpringAnimation de DynamicAnimation n'est compatible qu'avec le système View. La version Compose de spring utilise le même moteur physique mais fonctionne dans le contexte du Compose Animation System, se mettant automatiquement en pause lors du détachement.

Spring Animation vs Easing : quand choisir quoi

Spring Animation et les courbes Easing (easeInOut, FastOutSlowIn, decelerate) résolvent des problèmes différents. Les courbes Easing sont des trajectoires mathématiquement définies avec un temps fixe. Spring est une simulation physique où le temps dépend des paramètres et des conditions initiales. Pour les animations simples d'apparition/disparition, les courbes Easing suffisent. Pour les animations liées au mouvement de l'utilisateur (drag, swipe, scroll), Spring Animation offre une réponse plus naturelle.

ScénarioRecommandationParamètres
Apparition d'élémentSpring (damping = 0.7, stiffness = 400)Apparition douce avec léger dépassement
Swipe-to-dismissSpring + vitesse initialesetStartVelocity(velocity), damping = 0.5
Animation d'icôneSpring (damping = 0.3, stiffness = 600)Rebond notable pour les effets d'accent
Physique de scrollSpring (système)Ne pas personnaliser — Android gère
Changement de tailleEasing (FastOutSlowIn)Easing plus fiable pour les changements de layout

Anti-patrons : n'utilisez pas Spring Animation pour animer les paramètres de layout (largeur/hauteur de View via LayoutParams) — cela provoque un recalcul de hiérarchie à chaque image, entraînant des saccades et des chutes de FPS. Pour l'animation de couleur, les courbes Easing sont également préférables. Pour l'animation de la position de scroll, utilisez le Scroller système avec fling — Spring Animation n'offre aucun avantage ici. Pour des performances maximales sur Android, limitez le nombre d'instances SpringAnimation actives simultanément à 10–15.

Foire aux questions

Quelle est la différence entre damping et stiffness ?

Stiffness est la raideur du ressort (force de rappel). Une valeur élevée (1000) produit un mouvement rapide et brusque. Une valeur faible (100) produit un mouvement doux et lent. Damping est la résistance au mouvement. Une valeur faible (0.2) produit de longues oscillations avec rebond. Une valeur élevée (1.0) produit une absence d'oscillations, une décélération douce. Stiffness détermine la vitesse, damping détermine la présence et l'intensité des oscillations.

Comment choisir les bons paramètres de Spring Animation ?

Commencez avec damping = 0.5 et stiffness = 400 — c'est un ensemble de départ universel pour iOS et Android. Pour l'apparition d'éléments, augmentez damping à 0.7. Pour les effets d'accent (j'aime, ajouter au panier), réduisez damping à 0.3 avec stiffness = 600. Pour Material Motion, utilisez damping = 0.6 et stiffness = 300. Testez l'animation sur un appareil réel, pas sur un simulateur.

Spring Animation fonctionne-t-elle dans SwiftUI ?

Oui, dans SwiftUI l'animation à ressort est configurée via .animation(.spring(dampingFraction: 0.5, response: 0.5), value: state) ou .spring(blendDuration: 0.3) dans withAnimation. Les paramètres response et dampingFraction reflètent stiffness et damping d'UIKit. Pour les animations de glissement interactives, utilisez .interactiveSpring() — une version spéciale avec vitesse initiale pilotée par le geste optimisée pour les animations de glissement.

Pourquoi Spring Animation ne s'arrête-t-elle pas sur Android ?

Vérifiez SpringForce.finalPosition — s'il n'est pas défini ou égal à la valeur actuelle, l'animation peut ne pas démarrer. Appelez springAnim.cancel() dans onPause() de l'Activity/Fragment. Pour SpringAnimation dans RecyclerView, utilisez view.setOnDetachListener { animator.cancel() }. Pour Jetpack Compose, SpringAnimation se met automatiquement en pause lors des changements de composition.

Peut-on interrompre Spring Animation en douceur ?

Oui. Sur iOS, appelez view.layer.removeAnimation(forKey:) — l'animation s'arrête à l'image actuelle. Sur Android, appelez springAnim.cancel() — l'objet reste à la position actuelle. Pour une transition en douceur vers une nouvelle valeur cible, mettez à jour finalPosition et n'appelez pas cancel — SpringAnimation recalcule automatiquement la trajectoire. Pour SkipToEnd, utilisez springAnim.skipToEnd() sur Android.

Résumé

  • Spring Animation — animation basée sur un modèle physique de ressort avec paramètres de stiffness et damping.
  • Damping — coefficient d'amortissement (0 = oscillations infinies, 1 = amortissement critique).
  • Stiffness — raideur du ressort : 200 (souple), 600 (moyen), 1800 (élevé) sur Android.
  • iOS : UIView.animate avec usingSpringWithDamping (UIKit) ou CASpringAnimation (Core Animation).
  • Android : SpringAnimation + SpringForce d'AndroidX Dynamic Animation.
  • Jetpack Compose : animationSpec = spring(dampingRatio, stiffness) via Animatable.
  • Spring Animation est préférable à Easing pour les animations gestuelles (swipe, drag, pull-to-refresh).

Nous développerons une application mobile clé en main

IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.

Discuter du projet

Lisez aussi