|
|
|
@ -2,179 +2,177 @@ import { identity as linear, noop, run } from './utils.js';
|
|
|
|
|
import { loop } from './loop.js';
|
|
|
|
|
import { create_rule, delete_rule } from './style_manager.js';
|
|
|
|
|
|
|
|
|
|
let promise;
|
|
|
|
|
|
|
|
|
|
function wait() {
|
|
|
|
|
if (!promise) {
|
|
|
|
|
promise = Promise.resolve();
|
|
|
|
|
promise.then(() => {
|
|
|
|
|
promise = null;
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return promise;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let outros;
|
|
|
|
|
|
|
|
|
|
export function group_outros() {
|
|
|
|
|
outros = {
|
|
|
|
|
remaining: 0,
|
|
|
|
|
callbacks: []
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function wrapTransition(component, node, fn, params, intro) {
|
|
|
|
|
let obj = fn.call(component, node, params);
|
|
|
|
|
let config = fn.call(component, node, params);
|
|
|
|
|
let duration;
|
|
|
|
|
let ease;
|
|
|
|
|
let cssText;
|
|
|
|
|
|
|
|
|
|
let initialised = false;
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
t: intro ? 0 : 1,
|
|
|
|
|
running: false,
|
|
|
|
|
program: null,
|
|
|
|
|
pending: null,
|
|
|
|
|
let t = intro ? 0 : 1;
|
|
|
|
|
let running = false;
|
|
|
|
|
let running_program = null;
|
|
|
|
|
let pending_program = null;
|
|
|
|
|
|
|
|
|
|
run(b, callback) {
|
|
|
|
|
if (typeof obj === 'function') {
|
|
|
|
|
transitionManager.wait().then(() => {
|
|
|
|
|
obj = obj();
|
|
|
|
|
this._run(b, callback);
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
this._run(b, callback);
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
function start(program) {
|
|
|
|
|
node.dispatchEvent(new window.CustomEvent(`${program.b ? 'intro' : 'outro'}start`));
|
|
|
|
|
|
|
|
|
|
_run(b, callback) {
|
|
|
|
|
duration = obj.duration || 300;
|
|
|
|
|
ease = obj.easing || linear;
|
|
|
|
|
program.a = t;
|
|
|
|
|
program.delta = program.b - program.a;
|
|
|
|
|
program.duration = duration * Math.abs(program.b - program.a);
|
|
|
|
|
program.end = program.start + program.duration;
|
|
|
|
|
|
|
|
|
|
const program = {
|
|
|
|
|
start: window.performance.now() + (obj.delay || 0),
|
|
|
|
|
b,
|
|
|
|
|
callback: callback || noop
|
|
|
|
|
};
|
|
|
|
|
if (config.css) {
|
|
|
|
|
if (config.delay) node.style.cssText = cssText;
|
|
|
|
|
|
|
|
|
|
if (intro && !initialised) {
|
|
|
|
|
if (obj.css && obj.delay) {
|
|
|
|
|
cssText = node.style.cssText;
|
|
|
|
|
node.style.cssText += obj.css(0, 1);
|
|
|
|
|
}
|
|
|
|
|
program.name = create_rule(program, ease, config.css);
|
|
|
|
|
|
|
|
|
|
if (obj.tick) obj.tick(0, 1);
|
|
|
|
|
initialised = true;
|
|
|
|
|
}
|
|
|
|
|
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(', ');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!b) {
|
|
|
|
|
program.group = outros.current;
|
|
|
|
|
outros.current.remaining += 1;
|
|
|
|
|
}
|
|
|
|
|
running_program = program;
|
|
|
|
|
pending_program = null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (obj.delay) {
|
|
|
|
|
this.pending = program;
|
|
|
|
|
} else {
|
|
|
|
|
this.start(program);
|
|
|
|
|
}
|
|
|
|
|
function update(now) {
|
|
|
|
|
const program = running_program;
|
|
|
|
|
if (!program) return;
|
|
|
|
|
|
|
|
|
|
if (!this.running) {
|
|
|
|
|
this.running = true;
|
|
|
|
|
const p = now - program.start;
|
|
|
|
|
t = program.a + program.delta * ease(p / program.duration);
|
|
|
|
|
if (config.tick) config.tick(t, 1 - t);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const { abort, promise } = loop(now => {
|
|
|
|
|
if (this.program && now >= this.program.end) {
|
|
|
|
|
this.done();
|
|
|
|
|
}
|
|
|
|
|
function done() {
|
|
|
|
|
const program = running_program;
|
|
|
|
|
running_program = null;
|
|
|
|
|
|
|
|
|
|
if (this.pending && now >= this.pending.start) {
|
|
|
|
|
this.start(this.pending);
|
|
|
|
|
}
|
|
|
|
|
t = program.b;
|
|
|
|
|
|
|
|
|
|
if (this.running) {
|
|
|
|
|
this.update(now);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
if (config.tick) config.tick(t, 1 - t);
|
|
|
|
|
|
|
|
|
|
node.dispatchEvent(new window.CustomEvent(`${program.b ? 'intro' : 'outro'}end`));
|
|
|
|
|
|
|
|
|
|
start(program) {
|
|
|
|
|
node.dispatchEvent(new window.CustomEvent(`${program.b ? 'intro' : 'outro'}start`));
|
|
|
|
|
if (!program.b && !program.invalidated) {
|
|
|
|
|
program.group.callbacks.push(() => {
|
|
|
|
|
program.callback();
|
|
|
|
|
if (config.css) delete_rule(node, program.name);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (--program.group.remaining === 0) {
|
|
|
|
|
program.group.callbacks.forEach(run);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if (config.css) delete_rule(node, program.name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
running = !!pending_program;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (obj.css) {
|
|
|
|
|
if (obj.delay) node.style.cssText = cssText;
|
|
|
|
|
function go(b, callback) {
|
|
|
|
|
duration = config.duration || 300;
|
|
|
|
|
ease = config.easing || linear;
|
|
|
|
|
|
|
|
|
|
program.name = create_rule(program, ease, obj.css);
|
|
|
|
|
const program = {
|
|
|
|
|
start: window.performance.now() + (config.delay || 0),
|
|
|
|
|
b,
|
|
|
|
|
callback: callback || noop
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
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(', ');
|
|
|
|
|
if (intro && !initialised) {
|
|
|
|
|
if (config.css && config.delay) {
|
|
|
|
|
cssText = node.style.cssText;
|
|
|
|
|
node.style.cssText += config.css(0, 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.program = program;
|
|
|
|
|
this.pending = null;
|
|
|
|
|
},
|
|
|
|
|
if (config.tick) config.tick(0, 1);
|
|
|
|
|
initialised = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
update(now) {
|
|
|
|
|
const program = this.program;
|
|
|
|
|
if (!program) return;
|
|
|
|
|
if (!b) {
|
|
|
|
|
program.group = outros;
|
|
|
|
|
outros.remaining += 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
},
|
|
|
|
|
if (config.delay) {
|
|
|
|
|
pending_program = program;
|
|
|
|
|
} else {
|
|
|
|
|
start(program);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
done() {
|
|
|
|
|
const program = this.program;
|
|
|
|
|
this.program = null;
|
|
|
|
|
if (!running) {
|
|
|
|
|
running = true;
|
|
|
|
|
|
|
|
|
|
this.t = program.b;
|
|
|
|
|
const { abort, promise } = loop(now => {
|
|
|
|
|
if (running_program && now >= running_program.end) {
|
|
|
|
|
done();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (obj.tick) obj.tick(this.t, 1 - this.t);
|
|
|
|
|
if (pending_program && now >= pending_program.start) {
|
|
|
|
|
start(pending_program);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
node.dispatchEvent(new window.CustomEvent(`${program.b ? 'intro' : 'outro'}end`));
|
|
|
|
|
if (running) {
|
|
|
|
|
update(now);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!program.b && !program.invalidated) {
|
|
|
|
|
program.group.callbacks.push(() => {
|
|
|
|
|
program.callback();
|
|
|
|
|
if (obj.css) delete_rule(node, program.name);
|
|
|
|
|
return {
|
|
|
|
|
run(b, callback) {
|
|
|
|
|
if (typeof config === 'function') {
|
|
|
|
|
wait().then(() => {
|
|
|
|
|
config = config();
|
|
|
|
|
go(b, callback);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (--program.group.remaining === 0) {
|
|
|
|
|
program.group.callbacks.forEach(run);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if (obj.css) delete_rule(node, program.name);
|
|
|
|
|
go(b, callback);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.running = !!this.pending;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
abort(reset) {
|
|
|
|
|
if (reset && obj.tick) obj.tick(1, 0);
|
|
|
|
|
if (reset && config.tick) config.tick(1, 0);
|
|
|
|
|
|
|
|
|
|
if (this.program) {
|
|
|
|
|
if (obj.css) delete_rule(node, this.program.name);
|
|
|
|
|
this.program = this.pending = null;
|
|
|
|
|
this.running = false;
|
|
|
|
|
if (running_program) {
|
|
|
|
|
if (config.css) delete_rule(node, running_program.name);
|
|
|
|
|
running_program = pending_program = null;
|
|
|
|
|
running = false;
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
invalidate() {
|
|
|
|
|
if (this.program) {
|
|
|
|
|
this.program.invalidated = true;
|
|
|
|
|
if (running_program) {
|
|
|
|
|
running_program.invalidated = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export let outros = {};
|
|
|
|
|
|
|
|
|
|
export function groupOutros() {
|
|
|
|
|
outros.current = {
|
|
|
|
|
remaining: 0,
|
|
|
|
|
callbacks: []
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export var transitionManager = {
|
|
|
|
|
promise: null,
|
|
|
|
|
|
|
|
|
|
wait() {
|
|
|
|
|
if (!transitionManager.promise) {
|
|
|
|
|
transitionManager.promise = Promise.resolve();
|
|
|
|
|
transitionManager.promise.then(() => {
|
|
|
|
|
transitionManager.promise = null;
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return transitionManager.promise;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
}
|