diff --git a/packages/svelte/src/internal/client/dom/elements/transitions.js b/packages/svelte/src/internal/client/dom/elements/transitions.js index 5cd0870fdca0..6fbc585b4018 100644 --- a/packages/svelte/src/internal/client/dom/elements/transitions.js +++ b/packages/svelte/src/internal/client/dom/elements/transitions.js @@ -405,6 +405,7 @@ function animate(element, options, counterpart, t2, on_finish, on_abort) { animation.finished .then(() => { on_finish?.(); + on_finish = undefined; if (t2 === 1) { animation.cancel(); @@ -422,22 +423,25 @@ function animate(element, options, counterpart, t2, on_finish, on_abort) { } }); }); - } else { + } + + if (tick) { // Timer if (t1 === 0) { - tick?.(0, 1); // TODO put in nested effect, to avoid interleaved reads/writes? + tick(0, 1); // TODO put in nested effect, to avoid interleaved reads/writes? } task = loop((now) => { if (now >= end) { - tick?.(t2, 1 - t2); + tick(t2, 1 - t2); on_finish?.(); + on_finish = undefined; return false; } if (now >= start) { var p = t1 + delta * easing((now - start) / duration); - tick?.(p, 1 - p); + tick(p, 1 - p); } return true; diff --git a/packages/svelte/tests/runtime-legacy/samples/transition-css-and-js/_config.js b/packages/svelte/tests/runtime-legacy/samples/transition-css-and-js/_config.js new file mode 100644 index 000000000000..c0fde046bc3a --- /dev/null +++ b/packages/svelte/tests/runtime-legacy/samples/transition-css-and-js/_config.js @@ -0,0 +1,30 @@ +import { flushSync } from 'svelte'; +import { ok, test } from '../../test'; + +export default test({ + test({ assert, component, target, raf, logs }) { + const button = target.querySelector('button'); + + flushSync(() => button?.click()); + const div = target.querySelector('div'); + ok(div); + + let ended = 0; + div.addEventListener('introend', () => { + ended += 1; + }); + + assert.equal(div.style.scale, '0'); + assert.deepEqual(logs, ['tick: 0']); + + raf.tick(50); + assert.equal(div.style.scale, '0.5'); + assert.deepEqual(logs, ['tick: 0', 'tick: 0.5']); + + raf.tick(100); + assert.equal(div.style.scale, ''); + assert.deepEqual(logs, ['tick: 0', 'tick: 0.5', 'tick: 1']); + + assert.equal(ended, 1); + } +}); diff --git a/packages/svelte/tests/runtime-legacy/samples/transition-css-and-js/main.svelte b/packages/svelte/tests/runtime-legacy/samples/transition-css-and-js/main.svelte new file mode 100644 index 000000000000..2827f9cbe664 --- /dev/null +++ b/packages/svelte/tests/runtime-legacy/samples/transition-css-and-js/main.svelte @@ -0,0 +1,21 @@ + + + + +{#if visible} +
+{/if}