Lint and format ./src/runtime/internal/transitions.js

pull/8569/head
Simon Holthausen 3 years ago
parent 535e586d10
commit 155a438aa0

@ -12,13 +12,13 @@ let promise;
/** /**
* @returns {Promise<void>} */ * @returns {Promise<void>} */
function wait() { function wait() {
if (!promise) { if (!promise) {
promise = Promise.resolve(); promise = Promise.resolve();
promise.then(() => { promise.then(() => {
promise = null; promise = null;
}); });
} }
return promise; return promise;
} }
/** /**
@ -28,7 +28,7 @@ function wait() {
* @returns {void} * @returns {void}
*/ */
function dispatch(node, direction, kind) { function dispatch(node, direction, kind) {
node.dispatchEvent(custom_event(`${direction ? 'intro' : 'outro'}${kind}`)); node.dispatchEvent(custom_event(`${direction ? 'intro' : 'outro'}${kind}`));
} }
const outroing = new Set(); const outroing = new Set();
@ -39,20 +39,20 @@ let outros;
/** /**
* @returns {void} */ * @returns {void} */
export function group_outros() { export function group_outros() {
outros = { outros = {
r: 0, r: 0,
c: [], c: [],
p: outros // parent group p: outros // parent group
}; };
} }
/** /**
* @returns {void} */ * @returns {void} */
export function check_outros() { export function check_outros() {
if (!outros.r) { if (!outros.r) {
run_all(outros.c); run_all(outros.c);
} }
outros = outros.p; outros = outros.p;
} }
/** /**
@ -61,10 +61,10 @@ export function check_outros() {
* @returns {void} * @returns {void}
*/ */
export function transition_in(block, local) { export function transition_in(block, local) {
if (block && block.i) { if (block && block.i) {
outroing.delete(block); outroing.delete(block);
block.i(local); block.i(local);
} }
} }
/** /**
@ -74,23 +74,20 @@ export function transition_in(block, local) {
* @returns {void} * @returns {void}
*/ */
export function transition_out(block, local, detach, callback) { export function transition_out(block, local, detach, callback) {
if (block && block.o) { if (block && block.o) {
if (outroing.has(block)) if (outroing.has(block)) return;
return; outroing.add(block);
outroing.add(block); outros.c.push(() => {
outros.c.push(() => { outroing.delete(block);
outroing.delete(block); if (callback) {
if (callback) { if (detach) block.d(1);
if (detach) callback();
block.d(1); }
callback(); });
} block.o(local);
}); } else if (callback) {
block.o(local); callback();
} }
else if (callback) {
callback();
}
} }
/** /**
@ -104,77 +101,77 @@ const null_transition = { duration: 0 };
* @returns {{ start(): void; invalidate(): void; end(): void; }} * @returns {{ start(): void; invalidate(): void; end(): void; }}
*/ */
export function create_in_transition(node, fn, params) { export function create_in_transition(node, fn, params) {
/**
* @type {TransitionOptions} */
const options = { direction: 'in' };
let config = fn(node, params, options);
let running = false;
let animation_name;
let task;
let uid = 0;
/** /**
* @type {TransitionOptions} */ * @returns {void} */
const options = { direction: 'in' }; function cleanup() {
let config = fn(node, params, options); if (animation_name) delete_rule(node, animation_name);
let running = false; }
let animation_name;
let task;
let uid = 0;
/** /**
* @returns {void} */ * @returns {void} */
function cleanup() { function go() {
if (animation_name) const {
delete_rule(node, animation_name); delay = 0,
} duration = 300,
easing = linear,
/** tick = noop,
* @returns {void} */ css
function go() { } = config || null_transition;
const { delay = 0, duration = 300, easing = linear, tick = noop, css } = config || null_transition; if (css) animation_name = create_rule(node, 0, 1, duration, delay, easing, css, uid++);
if (css) tick(0, 1);
animation_name = create_rule(node, 0, 1, duration, delay, easing, css, uid++); const start_time = now() + delay;
tick(0, 1); const end_time = start_time + duration;
const start_time = now() + delay; if (task) task.abort();
const end_time = start_time + duration; running = true;
if (task) add_render_callback(() => dispatch(node, true, 'start'));
task.abort(); task = loop((now) => {
running = true; if (running) {
add_render_callback(() => dispatch(node, true, 'start')); if (now >= end_time) {
task = loop((now) => { tick(1, 0);
if (running) { dispatch(node, true, 'end');
if (now >= end_time) { cleanup();
tick(1, 0); return (running = false);
dispatch(node, true, 'end'); }
cleanup(); if (now >= start_time) {
return (running = false); const t = easing((now - start_time) / duration);
} tick(t, 1 - t);
if (now >= start_time) { }
const t = easing((now - start_time) / duration); }
tick(t, 1 - t); return running;
} });
} }
return running; let started = false;
}); return {
} start() {
let started = false; if (started) return;
return { started = true;
start() { delete_rule(node);
if (started) if (is_function(config)) {
return; config = config(options);
started = true; wait().then(go);
delete_rule(node); } else {
if (is_function(config)) { go();
config = config(options); }
wait().then(go); },
} invalidate() {
else { started = false;
go(); },
} end() {
}, if (running) {
invalidate() { cleanup();
started = false; running = false;
}, }
end() { }
if (running) { };
cleanup();
running = false;
}
}
};
} }
/** /**
@ -184,67 +181,69 @@ export function create_in_transition(node, fn, params) {
* @returns {{ end(reset: any): void; }} * @returns {{ end(reset: any): void; }}
*/ */
export function create_out_transition(node, fn, params) { export function create_out_transition(node, fn, params) {
/**
* @type {TransitionOptions} */
const options = { direction: 'out' };
let config = fn(node, params, options);
let running = true;
let animation_name;
const group = outros;
group.r += 1;
/** /**
* @type {TransitionOptions} */ * @returns {void} */
const options = { direction: 'out' }; function go() {
let config = fn(node, params, options); const {
let running = true; delay = 0,
let animation_name; duration = 300,
const group = outros; easing = linear,
group.r += 1; tick = noop,
css
/** } = config || null_transition;
* @returns {void} */ if (css) animation_name = create_rule(node, 1, 0, duration, delay, easing, css);
function go() { const start_time = now() + delay;
const { delay = 0, duration = 300, easing = linear, tick = noop, css } = config || null_transition; const end_time = start_time + duration;
if (css) add_render_callback(() => dispatch(node, false, 'start'));
animation_name = create_rule(node, 1, 0, duration, delay, easing, css); loop((now) => {
const start_time = now() + delay; if (running) {
const end_time = start_time + duration; if (now >= end_time) {
add_render_callback(() => dispatch(node, false, 'start')); tick(0, 1);
loop((now) => { dispatch(node, false, 'end');
if (running) { if (!--group.r) {
if (now >= end_time) { // this will result in `end()` being called,
tick(0, 1); // so we don't need to clean up here
dispatch(node, false, 'end'); run_all(group.c);
if (!--group.r) { }
// this will result in `end()` being called, return false;
// so we don't need to clean up here }
run_all(group.c); if (now >= start_time) {
} const t = easing((now - start_time) / duration);
return false; tick(1 - t, t);
} }
if (now >= start_time) { }
const t = easing((now - start_time) / duration); return running;
tick(1 - t, t); });
} }
} if (is_function(config)) {
return running; wait().then(() => {
}); // @ts-ignore
} config = config(options);
if (is_function(config)) { go();
wait().then(() => { });
// @ts-ignore } else {
config = config(options); go();
go(); }
}); return {
} end(reset) {
else { if (reset && config.tick) {
go(); config.tick(1, 0);
} }
return { if (running) {
end(reset) { if (animation_name) delete_rule(node, animation_name);
if (reset && config.tick) { running = false;
config.tick(1, 0); }
} }
if (running) { };
if (animation_name)
delete_rule(node, animation_name);
running = false;
}
}
};
} }
/** /**
@ -255,140 +254,145 @@ export function create_out_transition(node, fn, params) {
* @returns {{ run(b: 0 | 1): void; end(): void; }} * @returns {{ run(b: 0 | 1): void; end(): void; }}
*/ */
export function create_bidirectional_transition(node, fn, params, intro) { export function create_bidirectional_transition(node, fn, params, intro) {
/**
* @type {TransitionOptions} */
const options = { direction: 'both' };
let config = fn(node, params, options);
let t = intro ? 0 : 1;
/** /**
* @type {TransitionOptions} */ * @type {Program | null} */
const options = { direction: 'both' }; let running_program = null;
let config = fn(node, params, options);
let t = intro ? 0 : 1;
/** /**
* @type {Program | null} */ * @type {PendingProgram | null} */
let running_program = null; let pending_program = null;
let animation_name = null;
/** /**
* @type {PendingProgram | null} */ * @returns {void} */
let pending_program = null; function clear_animation() {
let animation_name = null; if (animation_name) delete_rule(node, animation_name);
}
/** /**
* @returns {void} */ * @param {PendingProgram} program
function clear_animation() { * @param {number} duration
if (animation_name) * @returns {Program}
delete_rule(node, animation_name); */
} function init(program, duration) {
const d = program.b - t;
duration *= Math.abs(d);
return {
a: t,
b: program.b,
d,
duration,
start: program.start,
end: program.start + duration,
group: program.group
};
}
/** /**
* @param {PendingProgram} program * @param {INTRO | OUTRO} b
* @param {number} duration * @returns {void}
* @returns {Program} */
*/ function go(b) {
function init(program, duration) { const {
const d = (program.b - t); delay = 0,
duration *= Math.abs(d); duration = 300,
return { easing = linear,
a: t, tick = noop,
b: program.b, css
d, } = config || null_transition;
duration,
start: program.start,
end: program.start + duration,
group: program.group
};
}
/** /**
* @param {INTRO | OUTRO} b * @type {PendingProgram} */
* @returns {void} const program = {
*/ start: now() + delay,
function go(b) { b
const { delay = 0, duration = 300, easing = linear, tick = noop, css } = config || null_transition; };
if (!b) {
/** // @ts-ignore todo: improve typings
* @type {PendingProgram} */ program.group = outros;
const program = { outros.r += 1;
start: now() + delay, }
b if (running_program || pending_program) {
}; pending_program = program;
if (!b) { } else {
// @ts-ignore todo: improve typings // if this is an intro, and there's a delay, we need to do
program.group = outros; // an initial tick and/or apply CSS animation immediately
outros.r += 1; if (css) {
} clear_animation();
if (running_program || pending_program) { animation_name = create_rule(node, t, b, duration, delay, easing, css);
pending_program = program; }
} if (b) tick(0, 1);
else { running_program = init(program, duration);
// if this is an intro, and there's a delay, we need to do add_render_callback(() => dispatch(node, b, 'start'));
// an initial tick and/or apply CSS animation immediately loop((now) => {
if (css) { if (pending_program && now > pending_program.start) {
clear_animation(); running_program = init(pending_program, duration);
animation_name = create_rule(node, t, b, duration, delay, easing, css); pending_program = null;
} dispatch(node, running_program.b, 'start');
if (b) if (css) {
tick(0, 1); clear_animation();
running_program = init(program, duration); animation_name = create_rule(
add_render_callback(() => dispatch(node, b, 'start')); node,
loop((now) => { t,
if (pending_program && now > pending_program.start) { running_program.b,
running_program = init(pending_program, duration); running_program.duration,
pending_program = null; 0,
dispatch(node, running_program.b, 'start'); easing,
if (css) { config.css
clear_animation(); );
animation_name = create_rule(node, t, running_program.b, running_program.duration, 0, easing, config.css); }
} }
} if (running_program) {
if (running_program) { if (now >= running_program.end) {
if (now >= running_program.end) { tick((t = running_program.b), 1 - t);
tick((t = running_program.b), 1 - t); dispatch(node, running_program.b, 'end');
dispatch(node, running_program.b, 'end'); if (!pending_program) {
if (!pending_program) { // we're done
// we're done if (running_program.b) {
if (running_program.b) { // intro — we can tidy up immediately
// intro — we can tidy up immediately clear_animation();
clear_animation(); } else {
} // outro — needs to be coordinated
else { if (!--running_program.group.r) run_all(running_program.group.c);
// outro — needs to be coordinated }
if (!--running_program.group.r) }
run_all(running_program.group.c); running_program = null;
} } else if (now >= running_program.start) {
} const p = now - running_program.start;
running_program = null; t = running_program.a + running_program.d * easing(p / running_program.duration);
} tick(t, 1 - t);
else if (now >= running_program.start) { }
const p = now - running_program.start; }
t = running_program.a + running_program.d * easing(p / running_program.duration); return !!(running_program || pending_program);
tick(t, 1 - t); });
} }
} }
return !!(running_program || pending_program); return {
}); run(b) {
} if (is_function(config)) {
} wait().then(() => {
return { const opts = { direction: b ? 'in' : 'out' };
run(b) { // @ts-ignore
if (is_function(config)) { config = config(opts);
wait().then(() => { go(b);
const opts = { direction: b ? 'in' : 'out' }; });
// @ts-ignore } else {
config = config(opts); go(b);
go(b); }
}); },
} end() {
else { clear_animation();
go(b); running_program = pending_program = null;
} }
}, };
end() {
clear_animation();
running_program = pending_program = null;
}
};
} }
/** @typedef {1} INTRO */ /** @typedef {1} INTRO */
/** @typedef {0} OUTRO */ /** @typedef {0} OUTRO */
/** @typedef {{ direction: 'in' | 'out' | 'both' }} TransitionOptions */ /** @typedef {{ direction: 'in' | 'out' | 'both' }} TransitionOptions */

Loading…
Cancel
Save