allow transition functions to return a function (#1431)

pull/1453/head
Rich Harris 7 years ago
parent b5931b95d4
commit 4c62d22b9c

@ -27,19 +27,12 @@ export function hash(str) {
} }
export function wrapTransition(component, node, fn, params, intro) { export function wrapTransition(component, node, fn, params, intro) {
const obj = fn(node, params); let obj = fn(node, params);
const duration = obj.duration || 300; let duration;
const ease = obj.easing || linear; let ease;
let cssText; let cssText;
if (intro) { let initialised = false;
if (obj.css && obj.delay) {
cssText = node.style.cssText;
node.style.cssText += obj.css(0, 1);
}
if (obj.tick) obj.tick(0, 1);
}
return { return {
t: intro ? 0 : 1, t: intro ? 0 : 1,
@ -48,12 +41,36 @@ export function wrapTransition(component, node, fn, params, intro) {
pending: null, pending: null,
run(b, callback) { 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 = { const program = {
start: window.performance.now() + (obj.delay || 0), start: window.performance.now() + (obj.delay || 0),
b, b,
callback: callback || noop 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) { if (!b) {
program.group = transitionManager.outros; program.group = transitionManager.outros;
transitionManager.outros.remaining += 1; transitionManager.outros.remaining += 1;
@ -154,6 +171,7 @@ export var transitionManager = {
bound: null, bound: null,
stylesheet: null, stylesheet: null,
activeRules: {}, activeRules: {},
promise: null,
add(transition) { add(transition) {
this.transitions.push(transition); this.transitions.push(transition);
@ -223,5 +241,16 @@ export var transitionManager = {
remaining: 0, remaining: 0,
callbacks: [] callbacks: []
}; };
},
wait() {
if (!transitionManager.promise) {
transitionManager.promise = Promise.resolve();
transitionManager.promise.then(() => {
transitionManager.promise = null;
});
}
return transitionManager.promise;
} }
}; };

@ -0,0 +1,15 @@
export default {
skipIntroByDefault: true,
test(assert, component, target, window, raf) {
component.set({ visible: true });
return Promise.resolve().then(() => {
const div = target.querySelector('div');
assert.equal(div.foo, 0);
raf.tick(50);
assert.equal(div.foo, 0.5);
});
},
};

@ -0,0 +1,20 @@
{#if visible}
<div transition:foo></div>
{/if}
<script>
export default {
transitions: {
foo(node, params) {
return () => {
return {
duration: 100,
tick: t => {
node.foo = t;
}
};
};
}
}
};
</script>
Loading…
Cancel
Save