From dd148f6956a9bcddd562c10a388023bad3ff391a Mon Sep 17 00:00:00 2001 From: Matth <42407879+TheSpeedM@users.noreply.github.com> Date: Tue, 7 Jan 2025 19:49:04 +0100 Subject: [PATCH 1/3] fix: Make Tween duration 0 set current to target immediately --- .changeset/cold-cups-act.md | 5 +++++ packages/svelte/src/motion/tweened.js | 9 +++++++++ packages/svelte/tests/motion/test.ts | 18 +++++++++++++++++- 3 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 .changeset/cold-cups-act.md diff --git a/.changeset/cold-cups-act.md b/.changeset/cold-cups-act.md new file mode 100644 index 000000000000..6776d4eef352 --- /dev/null +++ b/.changeset/cold-cups-act.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: Make Tween duration 0 set current to target immediately diff --git a/packages/svelte/src/motion/tweened.js b/packages/svelte/src/motion/tweened.js index 8aaefe5a2caf..62958a05e76e 100644 --- a/packages/svelte/src/motion/tweened.js +++ b/packages/svelte/src/motion/tweened.js @@ -240,6 +240,15 @@ export class Tween { interpolate = get_interpolator } = { ...this.#defaults, ...options }; + if (duration === 0) { + if (previous_task) { + previous_task.abort(); + previous_task = null; + } + set(this.#current, value); + return Promise.resolve(); + } + const start = raf.now() + delay; /** @type {(t: number) => T} */ diff --git a/packages/svelte/tests/motion/test.ts b/packages/svelte/tests/motion/test.ts index b6554e5e56ed..50606cbb86e2 100644 --- a/packages/svelte/tests/motion/test.ts +++ b/packages/svelte/tests/motion/test.ts @@ -2,7 +2,7 @@ import '../helpers.js'; // for the matchMedia polyfill import { describe, it, assert } from 'vitest'; import { get } from 'svelte/store'; -import { spring, tweened } from 'svelte/motion'; +import { spring, tweened, Tween } from 'svelte/motion'; describe('motion', () => { describe('spring', () => { @@ -39,4 +39,20 @@ describe('motion', () => { assert.equal(get(size), 20); }); }); + + describe('Tween', () => { + it('sets immediately when duration is 0', () => { + const size = new Tween(0); + + size.set(100, { duration: 0 }); + assert.equal(size.current, 100); + }) + }); + + it('updates correctly when initialized with a `null`-ish value', () => { + const size = new Tween(undefined as unknown as number, { duration: 0 }); + + size.set(10); + assert.equal(size.current, 10); + }); }); From 862677749be1e95c3abec40dfacc2bb1911773f7 Mon Sep 17 00:00:00 2001 From: Matth <42407879+TheSpeedM@users.noreply.github.com> Date: Tue, 7 Jan 2025 20:02:01 +0100 Subject: [PATCH 2/3] Run prettier on test file --- packages/svelte/tests/motion/test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/svelte/tests/motion/test.ts b/packages/svelte/tests/motion/test.ts index 50606cbb86e2..7d845bac3d05 100644 --- a/packages/svelte/tests/motion/test.ts +++ b/packages/svelte/tests/motion/test.ts @@ -46,7 +46,7 @@ describe('motion', () => { size.set(100, { duration: 0 }); assert.equal(size.current, 100); - }) + }); }); it('updates correctly when initialized with a `null`-ish value', () => { From f47ab966a87deef691860f4b549a9a3ba8fc1f68 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 7 Jan 2025 14:17:22 -0500 Subject: [PATCH 3/3] tweak --- packages/svelte/src/motion/tweened.js | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/packages/svelte/src/motion/tweened.js b/packages/svelte/src/motion/tweened.js index 62958a05e76e..36d32d1f72e5 100644 --- a/packages/svelte/src/motion/tweened.js +++ b/packages/svelte/src/motion/tweened.js @@ -230,9 +230,6 @@ export class Tween { set(value, options) { set(this.#target, value); - let previous_task = this.#task; - - let started = false; let { delay = 0, duration = 400, @@ -241,10 +238,7 @@ export class Tween { } = { ...this.#defaults, ...options }; if (duration === 0) { - if (previous_task) { - previous_task.abort(); - previous_task = null; - } + this.#task?.abort(); set(this.#current, value); return Promise.resolve(); } @@ -253,6 +247,8 @@ export class Tween { /** @type {(t: number) => T} */ let fn; + let started = false; + let previous_task = this.#task; this.#task = loop((now) => { if (now < start) {