From d245bab63a3fd4fbe3d0a03d51581db5b794564e Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Wed, 8 Jan 2025 09:49:49 +0000 Subject: [PATCH] feat: allow non-numeric values to be tweened by snapping immediately to new value (#14941) --- .changeset/cool-apples-report.md | 5 +++++ packages/svelte/src/motion/tweened.js | 3 ++- packages/svelte/tests/motion/test.ts | 21 +++++++++++++++++++++ 3 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 .changeset/cool-apples-report.md diff --git a/.changeset/cool-apples-report.md b/.changeset/cool-apples-report.md new file mode 100644 index 0000000000..fa76c036d1 --- /dev/null +++ b/.changeset/cool-apples-report.md @@ -0,0 +1,5 @@ +--- +'svelte': minor +--- + +feat: allow non-numeric values to be tweened by snapping immediately to new value diff --git a/packages/svelte/src/motion/tweened.js b/packages/svelte/src/motion/tweened.js index 36d32d1f72..31cddf8f30 100644 --- a/packages/svelte/src/motion/tweened.js +++ b/packages/svelte/src/motion/tweened.js @@ -72,7 +72,8 @@ function get_interpolator(a, b) { return (t) => a + t * delta; } - throw new Error(`Cannot interpolate ${type} values`); + // for non-numeric values, snap to the final value immediately + return () => b; } /** diff --git a/packages/svelte/tests/motion/test.ts b/packages/svelte/tests/motion/test.ts index 7d845bac3d..7d0403983a 100644 --- a/packages/svelte/tests/motion/test.ts +++ b/packages/svelte/tests/motion/test.ts @@ -3,6 +3,7 @@ import '../helpers.js'; // for the matchMedia polyfill import { describe, it, assert } from 'vitest'; import { get } from 'svelte/store'; import { spring, tweened, Tween } from 'svelte/motion'; +import { raf } from '../animation-helpers.js'; describe('motion', () => { describe('spring', () => { @@ -38,6 +39,16 @@ describe('motion', () => { size.update((v) => v + 10); assert.equal(get(size), 20); }); + + it('updates non-numeric values immediately', () => { + raf.reset(); + const boolean = tweened(false); + + boolean.set(true, { duration: 100 }); + + raf.tick(1); + assert.equal(get(boolean), true); + }); }); describe('Tween', () => { @@ -47,6 +58,16 @@ describe('motion', () => { size.set(100, { duration: 0 }); assert.equal(size.current, 100); }); + + it('updates non-numeric values immediately', () => { + raf.reset(); + const boolean = new Tween(false); + + boolean.set(true, { duration: 100 }); + + raf.tick(1); + assert.equal(boolean.current, true); + }); }); it('updates correctly when initialized with a `null`-ish value', () => {