diff --git a/src/compile/render-dom/wrappers/Element/index.ts b/src/compile/render-dom/wrappers/Element/index.ts index b9bf2ef734..0bf1dfa002 100644 --- a/src/compile/render-dom/wrappers/Element/index.ts +++ b/src/compile/render-dom/wrappers/Element/index.ts @@ -582,6 +582,7 @@ export default class ElementWrapper extends Wrapper { const { component } = this.renderer; if (intro === outro) { + // bidirectional transition const name = block.getUniqueName(`${this.var}_transition`); const snippet = intro.expression ? intro.expression.render(block) @@ -595,7 +596,7 @@ export default class ElementWrapper extends Wrapper { if (${name}) ${name}.invalidate(); @add_render_callback(() => { - if (!${name}) ${name} = @create_transition(${this.var}, ${fn}, ${snippet}, true); + if (!${name}) ${name} = @create_bidirectional_transition(${this.var}, ${fn}, ${snippet}, true); ${name}.run(1, () => { ${name} = null; }); @@ -603,7 +604,7 @@ export default class ElementWrapper extends Wrapper { `); block.builders.outro.addBlock(deindent` - if (!${name}) ${name} = @create_transition(${this.var}, ${fn}, ${snippet}, false); + if (!${name}) ${name} = @create_bidirectional_transition(${this.var}, ${fn}, ${snippet}, false); ${name}.run(0, () => { #outrocallback(); ${name} = null; @@ -611,7 +612,9 @@ export default class ElementWrapper extends Wrapper { `); block.builders.destroy.addConditional('detach', `if (${name}) ${name}.abort();`); - } else { + } + + else { const introName = intro && block.getUniqueName(`${this.var}_intro`); const outroName = outro && block.getUniqueName(`${this.var}_outro`); @@ -650,7 +653,7 @@ export default class ElementWrapper extends Wrapper { const fn = component.qualify(outro.name); block.builders.intro.addBlock(deindent` - if (${outroName}) ${outroName}.end(); + if (${outroName}) ${outroName}.end(1); `); // TODO hide elements that have outro'd (unless they belong to a still-outroing diff --git a/src/internal/transitions.js b/src/internal/transitions.js index f353bd5112..806e107b5a 100644 --- a/src/internal/transitions.js +++ b/src/internal/transitions.js @@ -30,12 +30,10 @@ export function create_in_transition(node, fn, params) { let animation_name; function cleanup() { - delete_rule(node, animation_name); + if (animation_name) delete_rule(node, animation_name); } - wait().then(() => { - if (typeof config === 'function') config = config(); - + function go() { const { delay = 0, duration = 300, @@ -56,13 +54,13 @@ export function create_in_transition(node, fn, params) { loop(now => { if (running) { - if (now > end_time) { + if (now >= end_time) { tick(1, 0); cleanup(); return running = false; } - if (now > start_time) { + if (now >= start_time) { const t = easing((now - start_time) / duration); tick(t, 1 - t); } @@ -70,7 +68,14 @@ export function create_in_transition(node, fn, params) { return running; }); - }); + } + + if (typeof config === 'function') { + config = config(); + wait().then(go); + } else { + go(); + } return { end() { @@ -92,7 +97,7 @@ export function create_out_transition(node, fn, params, callback) { group.remaining += 1; group.callbacks.push(callback); // TODO do we even need multiple callbacks? can we just have the one? - wait().then(() => { + function go() { if (typeof config === 'function') config = config(); const { @@ -113,7 +118,7 @@ export function create_out_transition(node, fn, params, callback) { loop(now => { if (running) { - if (now > end_time) { + if (now >= end_time) { tick(0, 1); if (!--group.remaining) { @@ -125,7 +130,7 @@ export function create_out_transition(node, fn, params, callback) { return false; } - if (now > start_time) { + if (now >= start_time) { const t = easing((now - start_time) / duration); tick(1 - t, t); } @@ -133,19 +138,30 @@ export function create_out_transition(node, fn, params, callback) { return running; }); - }); + } + + if (typeof config === 'function') { + config = config(); + wait().then(go); + } else { + go(); + } return { - end() { + end(reset) { + if (reset && config.tick) { + config.tick(1, 0); + } + if (running) { - delete_rule(node, animation_name); + if (animation_name) delete_rule(node, animation_name); running = false; } } }; } -export function create_transition(node, fn, params, intro) { +export function create_bidirectional_transition(node, fn, params, intro) { let config = fn(node, params); let ready = !intro; diff --git a/test/runtime/samples/transition-css-delay/_config.js b/test/runtime/samples/transition-css-delay/_config.js deleted file mode 100644 index 6e2c4a9ba4..0000000000 --- a/test/runtime/samples/transition-css-delay/_config.js +++ /dev/null @@ -1,10 +0,0 @@ -export default { - test({ assert, component, target, window, raf }) { - component.visible = true; - const div = target.querySelector('div'); - assert.strictEqual(div.style.opacity, '0'); - - raf.tick(50); - assert.strictEqual(div.style.opacity, ''); - } -}; \ No newline at end of file diff --git a/test/runtime/samples/transition-css-delay/main.html b/test/runtime/samples/transition-css-delay/main.html deleted file mode 100644 index faf89582e8..0000000000 --- a/test/runtime/samples/transition-css-delay/main.html +++ /dev/null @@ -1,17 +0,0 @@ - - -{#if visible} -