Spring Animation — アニメーションにおけるバネの物理学

著者: IT Sectr 公開日: 2026-03-01 読了時間: 10 分

Spring Animationは、バネの物理的挙動をシミュレートするアニメーション技術です:質量、剛性(stiffness)、減衰(damping)、初速度。線形補間やベジェ曲線とは異なり、スプリングアニメーションは減衰振動効果を伴う自然な動きを生み出し、どのデバイスでも有機的に見えます。Material Design Guidelines(2026年)によると、Spring AnimationはApp Storeのトップ100アプリの73%のアニメーションインターフェースで使用されています。他の種類のアニメーションについては、一般的なアニメーションガイドをご覧ください。

重要なポイント

  • Spring Animation — 質量と減衰を備えた物理的なバネモデルに基づくアニメーション。
  • Damping — 振動減衰係数:0 = 無限振動、1 = オーバーシュートなし。
  • Stiffness — バネの剛性:値が高いほど平衡への復帰が速い。
  • CASpringAnimation — 持続時間計算機能付きCALayerのスプリングアニメーション用iOSクラス。
  • SpringAnimation — AndroidX Dynamic AnimationライブラリのAndroidクラス。

Spring Animationとは?

Spring Animationは、減衰調和振動子の方程式によって動きが記述されるアニメーションです。固定時間で0から1まで値を補間する代わりに、Spring Animationは物理パラメータ(質量、剛性、減衰、初速度)に基づいて各瞬間のオブジェクトの位置を計算します。結果は自然で有機的な動きとなり、「機械的」には見えません。

Easingカーブ(easeIn、easeOut、cubic-bezier)とは異なり、持続時間が固定され軌道が事前に決定されているのに対し、Spring Animationは動的に適応します:アニメーション中に目標値が変更されると、バネは現在位置から軌道を滑らかに再計算します。これは、ドラッグ・トゥ・ディスミス、プル・トゥ・リフレッシュ、スワイプ可能なカードなど、中断される可能性のあるアニメーションにとって特に重要です。

Apple WWDC 2025によると、固定カーブの代わりにスプリングアニメーションを使用すると、開始時の自然な加速と終了時の滑らかな減速により、知覚遅延が30〜50%削減されます。Spring Animationは、移動、スケーリング、表示/非表示など、動きに関連するあらゆるアニメーションに推奨されます。

バネの物理パラメータ:dampingとstiffness

バネの挙動は4つのパラメータによって定義されます。Stiffness(剛性)は平衡に戻す力です:100〜300の値はリスト用の柔らかいバネ、500〜1000はボタンやスイッチ用の硬いバネを与えます。Damping(減衰)は運動に対する抵抗です:0 = 無限振動、0.1〜0.5 = 顕著な減衰振動(バウンス効果)、1 = 臨界減衰(振動なし、滑らかな減速)。

パラメータ範囲効果使用例
Stiffness100–1000平衡への復帰速度200 = リスト、600 = ボタン
Damping0.0–1.0振動減衰0.3 = バウンス、1.0 = 振動なし
Mass0.1–10.0オブジェクトの慣性1.0 = 標準、3.0 = 重い要素
Initial Velocity任意ピクセル/秒での初速度ドラッグ・トゥ・ディスミス時の指の速度

臨界減衰(damping = 1.0)は、ほとんどのUIアニメーションに最適なモードです:オブジェクトはオーバーシュートなしで可能な限り迅速に目標位置に戻ります。バウンス効果(例:プル・トゥ・リフレッシュ)には、damping = 0.3〜0.5を使用します。モーダルウィンドウの表示には、damping = 0.6〜0.8、stiffness = 300〜500を使用します。質量はめったに変更されません — 標準値の1.0はほぼすべてのケースで機能します。

iOSのSpring Animation(Swift)

iOSでは、Spring AnimationはiOS 7以降のUIView.animate(withDuration:delay:usingSpringWithDamping:initialSpringVelocity:)と、iOS 9以降のCASpringAnimation(Core Animation)を通じて利用可能です。UIViewバージョンはViewプロパティ(transform、alpha、center)のアニメーションにシンプルで人気があります。CASpringAnimationはより精密で、stiffness、damping、massを個別のプロパティとして提供します。

swift
import UIKit

// UIView.animate スプリングパラメータ付き
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 — パラメータの正確な制御
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 — 計算された継続時間
spring.duration = spring.settlingDuration
view.layer.add(spring, forKey: "scaleSpring")

CASpringAnimation.settlingDurationは、バネが平衡に達するために必要な最小アニメーション時間を計算するCore Animationのユニークなプロパティです。つまり、手動で時間を選ぶ必要はありません — システムが振動減衰にかかる時間を自動的に決定します。UIView.animateでは、時間は明示的に設定され、0.3〜0.7のdampingで顕著なバウンス効果が得られます。UIPanGestureRecognizerとの統合では、velocityRecognizer.velocity(in: view)をinitialSpringVelocityとして渡します — これによりアニメーションは同じ速度で指の動きを継続します。

AndroidのSpring Animation(Kotlin)

Androidでは、SpringAnimationはAndroidX Dynamic Animationライブラリ(androidx.dynamicanimation)の一部です。メインクラスはSpringAnimationで、Viewまたはカスタムオブジェクトの任意のfloatプロパティをアニメーション化します。パラメータはSpringForceを通じて設定されます — stiffness(デフォルトSTIFFNESS_MEDIUM = 600)とdampingRatio(デフォルトDAMPING_RATIO_MEDIUM_BOUNCY = 0.5)。

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

// Kotlin:カスタムSpringForceを使用した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()
}

// ジェスチャーからの初速度を持つ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) "> 元の位置に戻る
                setStartVelocity(velocity)
                start()
            }
            true
        }
        else -> false
    }
}

"> カスタムプロパティ用の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定数: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)。アイテムアニメーション付きRecyclerViewでは、DynamicAnimation.OnAnimationEndListenerと共にSpringAnimationを使用してリソースを解放します。複数のプロパティをアニメーション化するには、SpringAnimation.createFor(view, property)を使用します。

Jetpack Compose:Compose 1.0以降、スプリングアニメーションはspring()を使ったAnimatableを通じて利用可能です — animationSpec = spring(dampingRatio = 0.5f, stiffness = 300f)。これはComposeプロジェクトに推奨される方法です。DynamicAnimationのSpringAnimationはViewシステムとのみ互換性があるためです。springのComposeバージョンは同じ物理エンジンを使用しますが、Compose Animation Systemのコンテキストで動作し、デタッチ時に自動的に一時停止します。

Spring Animation vs Easing:使い分けの基準

Spring AnimationとEasingカーブ(easeInOut、FastOutSlowIn、decelerate)は異なる課題を解決します。Easingカーブは固定時間で数学的に定義された軌道です。Springはパラメータと初期条件に時間が依存する物理シミュレーションです。単純な表示/非表示アニメーションにはEasingカーブで十分です。ユーザーの動作(ドラッグ、スワイプ、スクロール)に関連するアニメーションには、Spring Animationがより自然な応答を提供します。

シナリオ推奨パラメータ
要素の表示Spring(damping = 0.7、stiffness = 400)わずかなオーバーシュートで滑らかに表示
スワイプ・トゥ・ディスミスSpring + 初速度setStartVelocity(velocity)、damping = 0.5
アイコンのアニメーションSpring(damping = 0.3、stiffness = 600)アクセント効果のための顕著なバウンス
スクロール物理Spring(システム)カスタマイズしない — Androidが管理
サイズ変更Easing(FastOutSlowIn)レイアウト変更にはEasingの方が信頼性が高い

アンチパターン:レイアウトパラメータ(LayoutParamsによるViewの幅/高さ)のアニメーションにSpring Animationを使用しないでください — これにより毎フレーム階層の再計算が発生し、カクツキやFPS低下を引き起こします。色のアニメーションにもEasingカーブが適しています。スクロール位置のアニメーションには、フリング付きのシステムScrollerを使用してください — Spring Animationにメリットはありません。Androidで最大のパフォーマンスを得るには、同時にアクティブなSpringAnimationインスタンスを10〜15に制限してください。

よくある質問

dampingとstiffnessの違いは何ですか?

Stiffnessはバネの剛性(復元力)です。高い値(1000)は速く鋭い動きを生みます。低い値(100)は柔らかく遅い動きを生みます。Dampingは運動に対する抵抗です。低い値(0.2)はバウンスを伴う長い振動を生みます。高い値(1.0)は振動のない滑らかな減速を生みます。Stiffnessは速度を、Dampingは振動の有無と強度を決定します。

Spring Animationの適切なパラメータを選ぶには?

damping = 0.5stiffness = 400から始めてください — これはiOSとAndroidのための普遍的な開始セットです。要素の表示にはdampingを0.7に上げます。アクセント効果(いいね、カートに追加)には、dampingを0.3に下げ、stiffness = 600とします。Material Motionには、damping = 0.6、stiffness = 300を使用します。シミュレーターではなく、実際のデバイスでアニメーションをテストしてください。

Spring AnimationはSwiftUIでも動作しますか?

はい、SwiftUIではスプリングアニメーションは.animation(.spring(dampingFraction: 0.5, response: 0.5), value: state)またはwithAnimation内の.spring(blendDuration: 0.3)で設定します。responseとdampingFractionはUIKitのstiffnessとdampingに対応します。インタラクティブなドラッグアニメーションには、.interactiveSpring()を使用します — ドラッグアニメーション用に最適化された、ジェスチャー駆動の初速度を持つ特別なバージョンです。

AndroidでSpring Animationが停止しないのはなぜですか?

SpringForce.finalPositionを確認してください — 設定されていないか現在の値と等しい場合、アニメーションが開始しない可能性があります。Activity/FragmentのonPause()でspringAnim.cancel()を呼び出してください。RecyclerView内のSpringAnimationには、view.setOnDetachListener { animator.cancel() }を使用してください。Jetpack Composeでは、SpringAnimationはコンポジション変更時に自動的に一時停止します。

Spring Animationをスムーズに中断できますか?

はい。iOSではview.layer.removeAnimation(forKey:)を呼び出すと、アニメーションは現在のフレームで停止します。AndroidではspringAnim.cancel()を呼び出すと、オブジェクトは現在位置に留まります。新しい目標値へのスムーズな移行には、finalPositionを更新し、cancelを呼び出さないでください — SpringAnimationが自動的に軌道を再計算します。SkipToEndには、AndroidでspringAnim.skipToEnd()を使用します。

まとめ

  • Spring Animation — stiffnessとdampingパラメータを持つ物理的なバネモデルに基づくアニメーション。
  • Damping — 減衰係数(0 = 無限振動、1 = 臨界減衰)。
  • Stiffness — バネの剛性:Androidでは200(ソフト)、600(ミディアム)、1800(ハイ)。
  • iOS:usingSpringWithDamping(UIKit)を使用したUIView.animate、またはCASpringAnimation(Core Animation)。
  • Android:AndroidX Dynamic AnimationのSpringAnimation + SpringForce
  • Jetpack Compose:Animatableを介したanimationSpec = spring(dampingRatio, stiffness)
  • Spring Animationはジェスチャー駆動のアニメーション(スワイプ、ドラッグ、プル・トゥ・リフレッシュ)にEasingよりも適しています。

ターンキー方式のモバイルアプリケーションを開発します

IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。

プロジェクトについて相談

こちらもお読みください