— the same envelope @fourjs/motion's DampedSpringTrajectory uses, here in
normalized progress rather than seconds. The parameters are pinned as
SPRING_DAMPING_RATIO (ζ) and SPRING_OSCILLATIONS (N, with
ω_d = 2πN) instead of a stiffness/mass pair, because an easing curve has no
duration of its own to make a frequency in hertz meaningful.
A real spring only reaches its rest position asymptotically: at t = 1 the
raw response still has E(1) = e^(−σ) ≈ 0.9 % of the range left to travel.
Dividing the whole curve by 1 − e^(−σ) (SPRING_NORMALIZATION)
removes that residue exactly, so the eased value lands on its target instead
of stopping 0.9 % short — the difference between a tween that arrives and one
that does not. The shape is otherwise unchanged (a 0.9 % uniform stretch).
Overshoots to about 1.32 on the first swing; not monotone.
Spring ease-out: the step response of an underdamped mass-spring-damper, normalized to start at 0 and end at exactly 1.
The closed form of
x'' + 2ζωₙx' + ωₙ²(x − 1) = 0withx(0) = 0,x'(0) = 0isx(t) = 1 − E(t)with the decay envelope— the same envelope
@fourjs/motion'sDampedSpringTrajectoryuses, here in normalized progress rather than seconds. The parameters are pinned as SPRING_DAMPING_RATIO (ζ) and SPRING_OSCILLATIONS (N, withω_d = 2πN) instead of a stiffness/mass pair, because an easing curve has no duration of its own to make a frequency in hertz meaningful.A real spring only reaches its rest position asymptotically: at
t = 1the raw response still hasE(1) = e^(−σ) ≈ 0.9 %of the range left to travel. Dividing the whole curve by1 − e^(−σ)(SPRING_NORMALIZATION) removes that residue exactly, so the eased value lands on its target instead of stopping 0.9 % short — the difference between a tween that arrives and one that does not. The shape is otherwise unchanged (a 0.9 % uniform stretch).Overshoots to about 1.32 on the first swing; not monotone.