🧮
Remotionコード分析 — spring()物理エンジンの内部実装
減衰スプリング微分方程式をJavaScriptでシミュレーションするspring()の数学とコード
GitHub: remotion-dev/remotion/packages/core/src/spring
spring()の滑らかなバウンスの秘密は減衰調和振動子の方程式: m*x'' + c*x' + k*x = 0。
判別式 D=c²-4mk が3種類の解を決定: overdamped(バウンスなし)、critically damped(最速収束)、underdamped(バウンスあり)。zeta比 damping/(2*sqrt(stiffness*mass)) がどのパスを選ぶか決定します。
measureSpring()は値が1の閾値内に収まるまでイテレーションしてスプリングアニメーションの持続フレーム数を事前計算します。
動作フロー
1
spring({frame, fps})がframe/fpsで時間(秒)を計算
2
zeta = damping / (2 * sqrt(stiffness * mass))で減衰比を計算
3
zeta < 1ならunderdamped: exp(-ζω₀t) * cos(ωDt)の解 → バウンスアニメーション
4
zeta ≥ 1ならoverdamped/critically damped: バウンスなしで1に収束
5
measureSpring()で|1-value| < 0.001になるフレームを見つけてdurationInFramesを決定
メリット
- ✓ 実際の物理学: CSS ease-in-outのような任意の曲線ではなく、物理法則に基づく自然なモーション
- ✓ 決定的: 同じframeに常に同じ値、数式なので100%再現可能
- ✓ measureSpring()でduration自動計算 → ハードコーディングなしで適切な長さを決定
デメリット
- ✗ 数学的理解が必要: 減衰比/固有振動数の概念を知らないとconfigチューニングが試行錯誤
ユースケース
spring configチューニング: mass/damping/stiffness値がビジュアル的にどんな効果か数学的に理解
カスタムイージング関数の実装: spring()のパターンを参考に独自の物理シミュレーションを制作