dock: keep vector spring stable at short animation speeds (#3991)

port 2.0
This commit is contained in:
Mario Mohar authored and GitHub committed 2026-10-28 14:24:29 -04:00
1 parent 46373f8bee
commit f5d22b101e
1 file changed
+10 -2
@@ -16,6 +16,7 @@ QtObject {
property real velocityEpsilon: 0.035
property real maximumFrameTime: 1 / 30
property real integrationStep: 1 / 240
property int maximumSubsteps: 256
readonly property real timeConstantMs: reducedMotion ? 0 : 2000 * mass / Math.max(1, damping)
property real currentWidth: 176
@@ -145,9 +146,11 @@ QtObject {
if (frameTime <= 0)
return;
const steps = Math.max(1, Math.ceil(frameTime / integrationStep));
const step = frameTime / steps;
const inverseMass = 1 / Math.max(0.001, mass);
// Short animation speeds scale stiffness by 1/f², so shrink the step until explicit Euler stays stable.
const stableStep = 1 / Math.max(1, damping * inverseMass, Math.sqrt(stiffness * inverseMass));
const steps = Math.min(maximumSubsteps, Math.max(1, Math.ceil(frameTime / Math.min(integrationStep, stableStep))));
const step = frameTime / steps;
const k = stiffness;
const c = damping;
const target = [targetWidth, targetHeight, targetOffsetAlong, targetOffsetCross, targetTopLeftRadius, targetTopRightRadius, targetBottomLeftRadius, targetBottomRightRadius];
@@ -162,6 +165,11 @@ QtObject {
}
}
if (!current.every(Number.isFinite) || !velocity.every(Number.isFinite)) {
settle();
return;
}
velocityWidth = velocity[0];
velocityHeight = velocity[1];
velocityOffsetAlong = velocity[2];