fix: prevent long delays causing erratic spring behaviour (#14940)

pull/14943/head
Rich Harris 3 days ago committed by GitHub
parent d245bab63a
commit 4d2cb2734b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: prevent long delays causing erratic spring behaviour

@ -108,12 +108,17 @@ export function spring(value, opts = {}) {
return false; return false;
} }
inv_mass = Math.min(inv_mass + inv_mass_recovery_rate, 1); inv_mass = Math.min(inv_mass + inv_mass_recovery_rate, 1);
// clamp elapsed time to 1/30th of a second, so that longer pauses
// (blocked thread or inactive tab) don't cause the spring to go haywire
const elapsed = Math.min(now - last_time, 1000 / 30);
/** @type {TickContext} */ /** @type {TickContext} */
const ctx = { const ctx = {
inv_mass, inv_mass,
opts: spring, opts: spring,
settled: true, settled: true,
dt: ((now - last_time) * 60) / 1000 dt: (elapsed * 60) / 1000
}; };
// @ts-ignore // @ts-ignore
const next_value = tick_spring(ctx, last_value, value, target_value); const next_value = tick_spring(ctx, last_value, value, target_value);
@ -236,6 +241,10 @@ export class Spring {
this.#task ??= loop((now) => { this.#task ??= loop((now) => {
this.#inverse_mass = Math.min(this.#inverse_mass + inv_mass_recovery_rate, 1); this.#inverse_mass = Math.min(this.#inverse_mass + inv_mass_recovery_rate, 1);
// clamp elapsed time to 1/30th of a second, so that longer pauses
// (blocked thread or inactive tab) don't cause the spring to go haywire
const elapsed = Math.min(now - this.#last_time, 1000 / 30);
/** @type {import('./private').TickContext} */ /** @type {import('./private').TickContext} */
const ctx = { const ctx = {
inv_mass: this.#inverse_mass, inv_mass: this.#inverse_mass,
@ -245,7 +254,7 @@ export class Spring {
precision: this.#precision.v precision: this.#precision.v
}, },
settled: true, settled: true,
dt: ((now - this.#last_time) * 60) / 1000 dt: (elapsed * 60) / 1000
}; };
var next = tick_spring(ctx, this.#last_value, this.#current.v, this.#target.v); var next = tick_spring(ctx, this.#last_value, this.#current.v, this.#target.v);

Loading…
Cancel
Save