argh i think i give up

pull/1781/head
Rich Harris 7 years ago
parent ea0064ba67
commit 7d934312aa

@ -698,22 +698,19 @@ export default class Element extends Node {
const fn = `%transitions-${intro.name}`;
block.builders.intro.addConditional(`#component._intro`, deindent`
if (${name}) ${name}.invalidate();
block.builders.hydrate.addLine(
`${name} = new @BidirectionalTransition(#component, ${this.var}, ${fn});`
);
block.builders.intro.addConditional(`#component._intro`, deindent`
#component.root._aftercreate.push(() => {
if (!${name}) ${name} = @wrapTransition(#component, ${this.var}, ${fn}, ${snippet}, true);
${name}.run(1);
${name}.intro(${snippet});
});
`);
block.builders.outro.addBlock(deindent`
if (!${name}) ${name} = @wrapTransition(#component, ${this.var}, ${fn}, ${snippet}, false);
${name}.run(0, () => {
#outrocallback();
${name} = null;
});
`);
block.builders.outro.addLine(
`${name}.outro(${snippet}, #outrocallback);`
);
} else {
const introName = intro && block.getUniqueName(`${this.var}_intro`);
const outroName = outro && block.getUniqueName(`${this.var}_outro`);

@ -27,18 +27,13 @@ export function hash(str) {
}
export class Transition {
constructor(component, node, fn) {
constructor(component, node, fn, counterpart) {
this.component = component;
this.node = node;
this.fn = fn;
this.cssText = node.style.cssText;
this.a = 0;
this.t = 0;
this.b = 1;
this.delta = 1;
this.duration = 300;
this.delay = 0;
this.ease = linear;
@ -46,6 +41,7 @@ export class Transition {
this.rule = '';
this.name = '';
this.counterpart = counterpart;
this.running = true;
this.started = false;
}
@ -74,37 +70,51 @@ export class Transition {
this.end = this.start + this.duration;
if (info.css) {
if (this.type === 'intro' && this.delay) node.style.cssText += info.css(this.a, 1 - this.a);
this.rule = generateRule(this, this.ease, info.css);
this.name = `__svelte_${hash(this.rule)}`;
if (this.type === 'intro' && this.delay) this.node.style.cssText += info.css(this.a, 1 - this.a);
}
if (this.type === 'intro' && info.tick) {
info.tick(this.a, 1 - this.a);
}
if (!this.delay) this.begin();
transitionManager.add(this);
}
update(now) {
if (now < this.start) return;
begin() {
if (this.counterpart) {
this.a = this.counterpart.t;
this.delta = this.b - this.a;
this.duration *= Math.abs(this.delta);
}
if (!this.started) {
this.component.fire(`${this.type}.start`, { node: this.node });
if (this.css) {
this.rule = generateRule(this, this.ease, this.css);
this.name = `__svelte_${hash(this.rule)}`;
}
if (this.rule) {
transitionManager.addRule(this.rule, this.name);
this.component.fire(`${this.type}.start`, { node: this.node });
this.node.style.animation = (this.node.style.animation || '')
.split(', ')
.filter(anim => anim && (this.delta < 0 || !/__svelte/.test(anim)))
.concat(`${this.name} ${this.duration}ms linear 1 forwards`)
.join(', ');
}
if (this.rule) {
if (this.type === 'intro' && this.delay) this.node.style.cssText = this.cssText;
this.started = true;
transitionManager.addRule(this.rule, this.name);
this.node.style.animation = (this.node.style.animation || '')
.split(', ')
.filter(anim => anim && (this.delta < 0 || !/__svelte/.test(anim)))
.concat(`${this.name} ${this.duration}ms linear 1 forwards`)
.join(', ');
}
this.started = true;
}
update(now) {
if (now < this.start) return;
if (!this.started) this.begin();
if (now >= this.end) return this.done();
const p = now - this.start;
@ -129,8 +139,8 @@ export class Transition {
}
export class Intro extends Transition {
constructor(component, node, fn) {
super(component, node, fn);
constructor(component, node, fn, counterpart) {
super(component, node, fn, counterpart);
this.type = 'intro';
@ -149,8 +159,8 @@ export class Intro extends Transition {
}
export class Outro extends Transition{
constructor(component, node, fn) {
super(component, node, fn);
constructor(component, node, fn, counterpart) {
super(component, node, fn, counterpart);
this.type = 'outro';
@ -192,143 +202,28 @@ export class Outro extends Transition{
}
}
export function wrapTransition(component, node, fn, params, intro) {
let obj = fn(node, params);
let duration;
let ease;
let cssText;
let initialised = false;
return {
t: intro ? 0 : 1,
running: false,
program: null,
pending: null,
run(b, callback) {
if (typeof obj === 'function') {
transitionManager.wait().then(() => {
obj = obj();
this._run(b, callback);
});
} else {
this._run(b, callback);
}
},
_run(b, callback) {
duration = obj.duration || 300;
ease = obj.easing || linear;
const program = {
start: window.performance.now() + (obj.delay || 0),
b,
callback: callback || noop
};
if (intro && !initialised) {
if (obj.css && obj.delay) {
cssText = node.style.cssText;
node.style.cssText += obj.css(0, 1);
}
if (obj.tick) obj.tick(0, 1);
initialised = true;
}
if (!b) {
program.group = transitionManager.outros;
transitionManager.outros.remaining += 1;
}
if (obj.delay) {
this.pending = program;
} else {
this.start(program);
}
if (!this.running) {
this.running = true;
transitionManager.add(this);
}
},
start(program) {
component.fire(`${program.b ? 'intro' : 'outro'}.start`, { node });
program.a = this.t;
program.delta = program.b - program.a;
program.duration = duration * Math.abs(program.b - program.a);
program.end = program.start + program.duration;
if (obj.css) {
if (obj.delay) node.style.cssText = cssText;
const rule = generateRule(program, ease, obj.css);
transitionManager.addRule(rule, program.name = '__svelte_' + hash(rule));
node.style.animation = (node.style.animation || '')
.split(', ')
.filter(anim => anim && (program.delta < 0 || !/__svelte/.test(anim)))
.concat(`${program.name} ${program.duration}ms linear 1 forwards`)
.join(', ');
}
this.program = program;
this.pending = null;
},
update(now) {
const program = this.program;
if (!program) return;
const p = now - program.start;
this.t = program.a + program.delta * ease(p / program.duration);
if (obj.tick) obj.tick(this.t, 1 - this.t);
},
done() {
const program = this.program;
this.t = program.b;
if (obj.tick) obj.tick(this.t, 1 - this.t);
export class BidirectionalTransition {
constructor(component, node, fn) {
this.component = component;
this.node = node;
this.fn = fn;
component.fire(`${program.b ? 'intro' : 'outro'}.end`, { node });
this.in = null;
this.out = null;
}
if (!program.b && !program.invalidated) {
program.group.callbacks.push(() => {
program.callback();
if (obj.css) transitionManager.deleteRule(node, program.name);
});
intro(params) {
if (this.out) this.out.invalidate();
this.in = new Intro(this.component, this.node, this.fn, this.out);
if (--program.group.remaining === 0) {
program.group.callbacks.forEach(fn => {
fn();
});
}
} else {
if (obj.css) transitionManager.deleteRule(node, program.name);
}
this.running = !!this.pending;
},
this.in.play(params);
}
abort() {
if (this.program) {
if (obj.tick) obj.tick(1, 0);
if (obj.css) transitionManager.deleteRule(node, this.program.name);
this.program = this.pending = null;
this.running = false;
}
},
outro(params, callback) {
this.out = new Outro(this.component, this.node, this.fn, this.in);
invalidate() {
if (this.program) {
this.program.invalidated = true;
}
}
};
this.out.play(params, callback);
}
}
export var transitionManager = {

Loading…
Cancel
Save