vaweGitHub

Springsreact-spring

react-spring molasses

It is the slowest preset in this set, 2.915 s. Its damping ratio is 3.59, so the extra friction holds the spring back. Stiffness 280, damping 120 and mass 1 give a damping ratio of 3.586, so the spring is overdamped. It settles to within 0.1% in 2.915 s. It never passes the end value.

Demo

Progress against time. The time axis runs 0 to 2.915 s, the settle time.0100.51progress50%90%
Dashed: a straight line. The dot and the line move with the box on the right.
react-spring molasses
linear

Both boxes take 2.915 s. This is real time.

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 (2915 ms) and a linear() string that follows the spring.

css linear()
transition: translate 2915ms linear(0, 0.0134, 0.0379, 0.0644, 0.0909, 0.1167, 0.1419, 0.1664, 0.1901, 0.2132, 0.2356, 0.2574, 0.2786, 0.2991, 0.3191, 0.3385, 0.3574, 0.3757, 0.3935, 0.4108, 0.4276, 0.4439, 0.4597, 0.4751, 0.4901, 0.5046, 0.5187, 0.5324, 0.5458, 0.5587, 0.5713, 0.5835, 0.5954, 0.6069, 0.6181, 0.629, 0.6396, 0.6498, 0.6598, 0.6695, 0.6789, 0.6881, 0.697, 0.7056, 0.714, 0.7222, 0.7301, 0.7378, 0.7452, 0.7525, 0.7596, 0.7664, 0.7731, 0.7795, 0.7858, 0.7919, 0.7978, 0.8036, 0.8092, 0.8146, 0.8199, 0.8251, 0.83, 0.8349, 0.8396, 0.8442, 0.8486, 0.8529, 0.8571, 0.8612, 0.8651, 0.869, 0.8727, 0.8763, 0.8799, 0.8833, 0.8866, 0.8899, 0.893, 0.896, 0.899, 0.9019, 0.9047, 0.9074, 0.91, 0.9126, 0.9151, 0.9175, 0.9199, 0.9221, 0.9244, 0.9265, 0.9286, 0.9306, 0.9326, 0.9345, 0.9364, 0.9382, 0.94, 0.9417, 0.9434, 0.945, 0.9465, 0.9481, 0.9495, 0.951, 0.9524, 0.9537, 0.9551, 0.9563, 0.9576, 0.9588, 0.96, 0.9611, 0.9622, 0.9633, 0.9643, 0.9654, 0.9663, 0.9673, 0.9682, 0.9691, 0.97, 0.9709, 0.9717, 0.9725, 0.9733, 0.9741, 0.9748, 0.9755, 0.9762, 0.9769, 0.9775, 0.9782, 0.9788, 0.9794, 0.98, 0.9806, 0.9811, 0.9817, 0.9822, 0.9827, 0.9832, 0.9837, 0.9841, 0.9846, 0.985, 0.9854, 0.9859, 0.9863, 0.9867, 0.987, 0.9874, 0.9878, 0.9881, 0.9885, 0.9888, 0.9891, 0.9894, 0.9897, 0.99, 0.9903, 0.9906, 0.9908, 0.9911, 0.9914, 0.9916, 0.9918, 0.9921, 0.9923, 0.9925, 0.9927, 0.9929, 0.9931, 0.9933, 0.9935, 0.9937, 0.9939, 0.9941, 0.9942, 0.9944, 0.9946, 0.9947, 0.9949, 0.995, 0.9951, 0.9953, 0.9954, 0.9956, 0.9957, 0.9958, 0.9959, 0.996, 0.9962, 0.9963, 0.9964, 0.9965, 0.9966, 0.9967, 0.9968, 0.9969, 0.9969, 0.997, 0.9971, 0.9972, 0.9973, 0.9974, 0.9974, 0.9975, 0.9976, 0.9976, 0.9977, 0.9978, 0.9978, 0.9979, 0.998, 0.998, 0.9981, 0.9981, 0.9982, 0.9982, 0.9983, 0.9983, 0.9984, 0.9984, 0.9985, 0.9985, 0.9986, 0.9986, 0.9986, 0.9987, 0.9987, 0.9988, 0.9988, 0.9988, 0.9989, 0.9989, 0.9989, 0.999, 0.999, 1);
web animations api
el.animate({ translate: ['0 0', '240px 0'] }, { duration: 2915, easing: 'linear(0, 0.0134, 0.0379, 0.0644, 0.0909, 0.1167, 0.1419, 0.1664, 0.1901, 0.2132, 0.2356, 0.2574, 0.2786, 0.2991, 0.3191, 0.3385, 0.3574, 0.3757, 0.3935, 0.4108, 0.4276, 0.4439, 0.4597, 0.4751, 0.4901, 0.5046, 0.5187, 0.5324, 0.5458, 0.5587, 0.5713, 0.5835, 0.5954, 0.6069, 0.6181, 0.629, 0.6396, 0.6498, 0.6598, 0.6695, 0.6789, 0.6881, 0.697, 0.7056, 0.714, 0.7222, 0.7301, 0.7378, 0.7452, 0.7525, 0.7596, 0.7664, 0.7731, 0.7795, 0.7858, 0.7919, 0.7978, 0.8036, 0.8092, 0.8146, 0.8199, 0.8251, 0.83, 0.8349, 0.8396, 0.8442, 0.8486, 0.8529, 0.8571, 0.8612, 0.8651, 0.869, 0.8727, 0.8763, 0.8799, 0.8833, 0.8866, 0.8899, 0.893, 0.896, 0.899, 0.9019, 0.9047, 0.9074, 0.91, 0.9126, 0.9151, 0.9175, 0.9199, 0.9221, 0.9244, 0.9265, 0.9286, 0.9306, 0.9326, 0.9345, 0.9364, 0.9382, 0.94, 0.9417, 0.9434, 0.945, 0.9465, 0.9481, 0.9495, 0.951, 0.9524, 0.9537, 0.9551, 0.9563, 0.9576, 0.9588, 0.96, 0.9611, 0.9622, 0.9633, 0.9643, 0.9654, 0.9663, 0.9673, 0.9682, 0.9691, 0.97, 0.9709, 0.9717, 0.9725, 0.9733, 0.9741, 0.9748, 0.9755, 0.9762, 0.9769, 0.9775, 0.9782, 0.9788, 0.9794, 0.98, 0.9806, 0.9811, 0.9817, 0.9822, 0.9827, 0.9832, 0.9837, 0.9841, 0.9846, 0.985, 0.9854, 0.9859, 0.9863, 0.9867, 0.987, 0.9874, 0.9878, 0.9881, 0.9885, 0.9888, 0.9891, 0.9894, 0.9897, 0.99, 0.9903, 0.9906, 0.9908, 0.9911, 0.9914, 0.9916, 0.9918, 0.9921, 0.9923, 0.9925, 0.9927, 0.9929, 0.9931, 0.9933, 0.9935, 0.9937, 0.9939, 0.9941, 0.9942, 0.9944, 0.9946, 0.9947, 0.9949, 0.995, 0.9951, 0.9953, 0.9954, 0.9956, 0.9957, 0.9958, 0.9959, 0.996, 0.9962, 0.9963, 0.9964, 0.9965, 0.9966, 0.9967, 0.9968, 0.9969, 0.9969, 0.997, 0.9971, 0.9972, 0.9973, 0.9974, 0.9974, 0.9975, 0.9976, 0.9976, 0.9977, 0.9978, 0.9978, 0.9979, 0.998, 0.998, 0.9981, 0.9981, 0.9982, 0.9982, 0.9983, 0.9983, 0.9984, 0.9984, 0.9985, 0.9985, 0.9986, 0.9986, 0.9986, 0.9987, 0.9987, 0.9988, 0.9988, 0.9988, 0.9989, 0.9989, 0.9989, 0.999, 0.999, 1)', fill: 'both' });
vawe
import { spring, springDuration, springLinear } from '../../core/motion/springs.js';

const k = 280, d = 120;

// 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: 2915 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
280k, with mass 1
Damping
120d, with mass 1
Damping ratio
3.586overdamped
Settle time
2.915 swithin 0.1% of the end
Overshoot
0%stays inside the end
Crosses the end
0times
50% of travel
0.3 s10% of the settle time
90% of travel
0.976 s33% of the settle time
Natural frequency
16.73 rad/ssqrt(k)
Ring period
noneit does not oscillate
Peak speed
6.32xtimes the average speed
linear() points
241within 0.26% 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

react-spring@react-spring/core 10.1.2
config.molasses = { tension: 280, friction: 120 }packages/core/src/constants.ts, const config

Conversion: Stiffness is tension and damping is friction, with mass 1 (the default). The physics loop in the same package, acceleration = (-tension x displacement - friction x velocity) / mass, is the spring that spring() in springs.js solves.

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