popmotion
Version:
The animator's toolbox
75 lines • 3.02 kB
JavaScript
import { warning } from "hey-listen";
import { clamp } from "../../utils/clamp";
var safeMin = 0.001;
export var minDuration = 0.01;
export var maxDuration = 10.0;
export var minDamping = 0.05;
export var maxDamping = 1;
export function findSpring(_a) {
var _b = _a.duration, duration = _b === void 0 ? 800 : _b, _c = _a.bounce, bounce = _c === void 0 ? 0.25 : _c, _d = _a.velocity, velocity = _d === void 0 ? 0 : _d, _e = _a.mass, mass = _e === void 0 ? 1 : _e;
var envelope;
var derivative;
warning(duration <= maxDuration * 1000, "Spring duration must be 10 seconds or less");
var dampingRatio = 1 - bounce;
dampingRatio = clamp(minDamping, maxDamping, dampingRatio);
duration = clamp(minDuration, maxDuration, duration / 1000);
if (dampingRatio < 1) {
envelope = function (undampedFreq) {
var exponentialDecay = undampedFreq * dampingRatio;
var delta = exponentialDecay * duration;
var a = exponentialDecay - velocity;
var b = calcAngularFreq(undampedFreq, dampingRatio);
var c = Math.exp(-delta);
return safeMin - (a / b) * c;
};
derivative = function (undampedFreq) {
var exponentialDecay = undampedFreq * dampingRatio;
var delta = exponentialDecay * duration;
var d = delta * velocity + velocity;
var e = Math.pow(dampingRatio, 2) * Math.pow(undampedFreq, 2) * duration;
var f = Math.exp(-delta);
var g = calcAngularFreq(Math.pow(undampedFreq, 2), dampingRatio);
var factor = -envelope(undampedFreq) + safeMin > 0 ? -1 : 1;
return (factor * ((d - e) * f)) / g;
};
}
else {
envelope = function (undampedFreq) {
var a = Math.exp(-undampedFreq * duration);
var b = (undampedFreq - velocity) * duration + 1;
return -safeMin + a * b;
};
derivative = function (undampedFreq) {
var a = Math.exp(-undampedFreq * duration);
var b = (velocity - undampedFreq) * (duration * duration);
return a * b;
};
}
var initialGuess = 5 / duration;
var undampedFreq = approximateRoot(envelope, derivative, initialGuess);
if (isNaN(undampedFreq)) {
return {
stiffness: 100,
damping: 10,
};
}
else {
var stiffness = Math.pow(undampedFreq, 2) * mass;
return {
stiffness: stiffness,
damping: dampingRatio * 2 * Math.sqrt(mass * stiffness),
};
}
}
var rootIterations = 12;
function approximateRoot(envelope, derivative, initialGuess) {
var result = initialGuess;
for (var i = 1; i < rootIterations; i++) {
result = result - envelope(result) / derivative(result);
}
return result;
}
export function calcAngularFreq(undampedFreq, dampingRatio) {
return undampedFreq * Math.sqrt(1 - dampingRatio * dampingRatio);
}
//# sourceMappingURL=find-spring.js.map