diff --git a/src/generators/dom/visitors/Element/addTransitions.js b/src/generators/dom/visitors/Element/addTransitions.js index d053d89edb..526a9df6cc 100644 --- a/src/generators/dom/visitors/Element/addTransitions.js +++ b/src/generators/dom/visitors/Element/addTransitions.js @@ -31,18 +31,23 @@ export default function addTransitions ( generator, block, state, node, intro, o } else { + const introName = intro && block.getUniqueName( `${state.name}_intro` ); + const outroName = outro && block.getUniqueName( `${state.name}_outro` ); + if ( intro ) { - const name = block.getUniqueName( `${state.name}_intro` ); + block.addVariable( introName ); const snippet = intro.expression ? block.contextualise( intro.expression ).snippet : '{}'; - block.addVariable( name ); - const fn = `${generator.alias( 'template' )}.transitions.${intro.name}`; // TODO add built-in transitions? + if ( outro ) { + block.builders.intro.addBlock( `if ( ${outroName} ) ${outroName}.abort();` ); + } + block.builders.intro.addBlock( deindent` ${block.component}._renderHooks.push( function () { - ${name} = ${wrapTransition}( ${state.name}, ${fn}, ${snippet}, true, null ); - ${name}.run( 0, 1, function () { + ${introName} = ${wrapTransition}( ${state.name}, ${fn}, ${snippet}, true, null ); + ${introName}.run( 0, 1, function () { ${block.component}.fire( 'intro.end', { node: ${state.name} }); }); }); @@ -50,16 +55,14 @@ export default function addTransitions ( generator, block, state, node, intro, o } if ( outro ) { - const name = block.getUniqueName( `${state.name}_intro` ); + block.addVariable( outroName ); const snippet = outro.expression ? block.contextualise( outro.expression ).snippet : '{}'; - block.addVariable( name ); - const fn = `${generator.alias( 'template' )}.transitions.${outro.name}`; block.builders.outro.addBlock( deindent` - ${name} = ${wrapTransition}( ${state.name}, ${fn}, ${snippet}, false, null ); - ${name}.run( 1, 0, function () { + ${outroName} = ${wrapTransition}( ${state.name}, ${fn}, ${snippet}, false, null ); + ${outroName}.run( 1, 0, function () { detachNode( ${state.name} ); ${block.component}.fire( 'outro.end', { node: ${state.name} }); if ( --${block.alias( 'outros' )} === 0 ) ${block.alias( 'outrocallback' )}(); diff --git a/src/generators/dom/visitors/IfBlock.js b/src/generators/dom/visitors/IfBlock.js index c4f1a435f8..00ddd049e3 100644 --- a/src/generators/dom/visitors/IfBlock.js +++ b/src/generators/dom/visitors/IfBlock.js @@ -89,6 +89,7 @@ function simple ( generator, block, state, node, branch, dynamic, { name, anchor const exit = branch.hasOutroTransitions ? deindent` ${name}.outro( function () { + ${name}.destroy( true ); ${name} = null; }); ` : diff --git a/src/shared/transitions.js b/src/shared/transitions.js index 65a3b23ff3..ddf3c55b3b 100644 --- a/src/shared/transitions.js +++ b/src/shared/transitions.js @@ -64,17 +64,16 @@ export function wrapTransition ( node, fn, params, intro, outgroup ) { var style = document.createElement( 'style' ); var cleanup = function () { - if ( !transition.running ) return; document.head.removeChild( style ); transition.running = false; }; return assign( transition, { generateKeyframes: function () { - id = 'svelte_' + ~~( Math.random() * 1e9 ); // TODO make this more robust + id = '__svelte' + ~~( Math.random() * 1e9 ); // TODO make this more robust var keyframes = '@keyframes ' + id + '{\n'; - for ( var p = 0; p <= 1; p += 166.666 / this.duration ) { + for ( var p = 0; p <= 1; p += 16.666 / this.duration ) { var t = this.a + this.d * ease( p ); var styles = obj.styles( ease( t ) ); keyframes += ( p * 100 ) + '%{' + styles + '}\n'; @@ -85,7 +84,14 @@ export function wrapTransition ( node, fn, params, intro, outgroup ) { style.textContent += keyframes; document.head.appendChild( style ); - node.style.animation += ( node.style.animation ? ', ' : '' ) + id + ' ' + this.duration + 'ms linear 1 forwards'; + var d = this.d; + node.style.animation = node.style.animation.split( ',' ) + .filter( function ( anim ) { + // when introing, discard old animations if there are any + return anim && ( d < 0 || !/__svelte/.test( anim ) ); + }) + .concat( id + ' ' + this.duration + 'ms linear 1 forwards' ) + .join( ', ' ); }, update: function ( now ) { const p = now - this.start;