vaweGitHub

SpringsMotion (Framer Motion)

Motion x, y and rotate default

Motion uses it for a transform value (x, y, rotate) with two keyframes, when you set no transition. A scale value gets the next preset. Stiffness 500, damping 25 and mass 1 give a damping ratio of 0.559, so the spring is underdamped. It settles to within 0.1% in 0.565 s. It passes the end value by up to 12% at 0.169 s and crosses it 3 times.

Demo

Progress against time. The time axis runs 0 to 0.565 s, the settle time.0100.51progress50%90%
Dashed: a straight line. The dot and the line move with the box on the right.
Motion x, y and rotate default
linear

Both boxes take 0.565 s. Playing at 0.5× speed.

Your system asks for reduced motion, so nothing plays. The chart shows the whole move.

Code

A spring has no fixed duration, so the CSS takes the settle time (565 ms) and a linear() string that follows the spring.

css linear()
transition: translate 565ms linear(0, 0.0053, 0.0205, 0.0441, 0.0752, 0.1124, 0.1548, 0.2013, 0.251, 0.303, 0.3565, 0.4108, 0.4652, 0.5192, 0.5722, 0.6237, 0.6735, 0.7212, 0.7665, 0.8091, 0.8491, 0.8862, 0.9203, 0.9515, 0.9798, 1.0051, 1.0275, 1.0472, 1.0642, 1.0786, 1.0906, 1.1004, 1.108, 1.1136, 1.1174, 1.1196, 1.1203, 1.1196, 1.1178, 1.1149, 1.1112, 1.1067, 1.1016, 1.096, 1.09, 1.0837, 1.0773, 1.0708, 1.0642, 1.0578, 1.0514, 1.0452, 1.0392, 1.0335, 1.028, 1.0229, 1.0181, 1.0136, 1.0095, 1.0058, 1.0024, 0.9994, 0.9967, 0.9943, 0.9923, 0.9905, 0.9891, 0.9879, 0.987, 0.9863, 0.9859, 0.9856, 0.9855, 0.9856, 0.9858, 0.9862, 0.9866, 0.9872, 0.9878, 0.9885, 0.9892, 0.9899, 0.9907, 0.9915, 0.9923, 0.9931, 0.9938, 0.9946, 0.9953, 0.996, 0.9966, 0.9973, 0.9978, 0.9984, 0.9989, 0.9993, 0.9997, 1.0001, 1.0004, 1.0007, 1.0009, 1.0011, 1.0013, 1.0015, 1.0016, 1.0016, 1.0017, 1.0017, 1.0017, 1.0017, 1.0017, 1.0017, 1.0016, 1.0015, 1.0015, 1.0014, 1.0013, 1.0012, 1.0011, 1.001, 1);
web animations api
el.animate({ translate: ['0 0', '240px 0'] }, { duration: 565, easing: 'linear(0, 0.0053, 0.0205, 0.0441, 0.0752, 0.1124, 0.1548, 0.2013, 0.251, 0.303, 0.3565, 0.4108, 0.4652, 0.5192, 0.5722, 0.6237, 0.6735, 0.7212, 0.7665, 0.8091, 0.8491, 0.8862, 0.9203, 0.9515, 0.9798, 1.0051, 1.0275, 1.0472, 1.0642, 1.0786, 1.0906, 1.1004, 1.108, 1.1136, 1.1174, 1.1196, 1.1203, 1.1196, 1.1178, 1.1149, 1.1112, 1.1067, 1.1016, 1.096, 1.09, 1.0837, 1.0773, 1.0708, 1.0642, 1.0578, 1.0514, 1.0452, 1.0392, 1.0335, 1.028, 1.0229, 1.0181, 1.0136, 1.0095, 1.0058, 1.0024, 0.9994, 0.9967, 0.9943, 0.9923, 0.9905, 0.9891, 0.9879, 0.987, 0.9863, 0.9859, 0.9856, 0.9855, 0.9856, 0.9858, 0.9862, 0.9866, 0.9872, 0.9878, 0.9885, 0.9892, 0.9899, 0.9907, 0.9915, 0.9923, 0.9931, 0.9938, 0.9946, 0.9953, 0.996, 0.9966, 0.9973, 0.9978, 0.9984, 0.9989, 0.9993, 0.9997, 1.0001, 1.0004, 1.0007, 1.0009, 1.0011, 1.0013, 1.0015, 1.0016, 1.0016, 1.0017, 1.0017, 1.0017, 1.0017, 1.0017, 1.0017, 1.0016, 1.0015, 1.0015, 1.0014, 1.0013, 1.0012, 1.0011, 1.001, 1)', fill: 'both' });
vawe
import { spring, springDuration, springLinear } from '../../core/motion/springs.js';

const k = 500, d = 25;

// per-frame code (window.seek, vawe.onFrame): t is seconds since the move starts
const x = 240 * spring(t, k, d);

// CSS and Web Animations: 565 ms, the linear() string above
el.animate(
  { translate: ['0 0', '240px 0'] },
  { duration: springDuration(k, d) * 1000, easing: springLinear(k, d), fill: 'both' },
);

Numbers

Stiffness
500k, with mass 1
Damping
25d, with mass 1
Damping ratio
0.559underdamped
Settle time
0.565 swithin 0.1% of the end
Overshoot
12%peak at 0.169 s
Crosses the end
3times
50% of travel
0.06 s11% of the settle time
90% of travel
0.101 s18% of the settle time
Natural frequency
22.36 rad/ssqrt(k)
Ring period
0.339 sone swing of the overshoot
Peak speed
6.53xtimes the average speed
linear() points
121within 0.13% of travel

Computed with spring() and springDuration() from core/motion/springs.js. The settle time is the last moment the spring is more than 0.1% away from the end value; a library stops its own spring by its own rest thresholds, so its clock can run shorter.

Source of the numbers

Motion (Framer Motion)motion-dom 14.9.0 (motion and framer-motion 14.9.0)
underDampedSpring = { type: "spring", stiffness: 500, damping: 25, restSpeed: 10 }underDampedSpring in animation/utils/default-transitions.ts

Conversion: Stiffness and damping are used as they are, with mass 1.

The four closest curves in this set, by the average gap between the two springs over their first seconds. A gap of 0.01 is invisible; 0.1 is a different feel.

More springs