support parameterised animations

pull/1468/head
Rich Harris 7 years ago
parent 31e387e76c
commit 276af83cb7

@ -6,8 +6,6 @@ export function wrapAnimation(node, from, fn, params) {
const to = node.getBoundingClientRect();
if (from.left === to.left && from.right === to.right && from.top === to.top && from.bottom === to.bottom) return;
// console.log({ x: from.x, y: from.y }, { x: to.x, y: to.y }, node.textContent.trim())
const info = fn(node, { from, to }, params);
const duration = 'duration' in info ? info.duration : 300;
@ -26,13 +24,17 @@ export function wrapAnimation(node, from, fn, params) {
end
};
const cssText = node.style.cssText;
const animation = {
pending: delay ? program : null,
program: delay ? null : program,
running: !delay,
running: true,
start() {
if (info.css) {
if (delay) node.style.cssText = cssText;
const rule = generateRule(program, ease, info.css);
program.name = `__svelte_${hash(rule)}`;
@ -44,6 +46,9 @@ export function wrapAnimation(node, from, fn, params) {
.concat(`${program.name} ${program.duration}ms linear 1 forwards`)
.join(', ');
}
animation.program = program;
animation.pending = null;
},
update: now => {
@ -54,7 +59,7 @@ export function wrapAnimation(node, from, fn, params) {
done() {
if (info.tick) info.tick(1, 0);
this.stop();
animation.stop();
},
stop() {
@ -66,7 +71,12 @@ export function wrapAnimation(node, from, fn, params) {
transitionManager.add(animation);
if (info.tick) info.tick(0, 1);
if (!delay) animation.start();
if (delay) {
if (info.css) node.style.cssText += info.css(0, 1);
} else {
animation.start();
}
return animation;
}

@ -0,0 +1,62 @@
export default {
data: {
things: [
{ id: 1, name: 'a' },
{ id: 2, name: 'b' },
{ id: 3, name: 'c' },
{ id: 4, name: 'd' },
{ id: 5, name: 'e' }
]
},
html: `
<div>a</div>
<div>b</div>
<div>c</div>
<div>d</div>
<div>e</div>
`,
test(assert, component, target, window, raf) {
let divs = document.querySelectorAll('div');
divs.forEach(div => {
div.getBoundingClientRect = function() {
const index = [...this.parentNode.children].indexOf(this);
const top = index * 30;
return {
left: 0,
right: 100,
top,
bottom: top + 20
}
};
})
component.set({
things: [
{ id: 5, name: 'e' },
{ id: 2, name: 'b' },
{ id: 3, name: 'c' },
{ id: 4, name: 'd' },
{ id: 1, name: 'a' }
]
});
divs = document.querySelectorAll('div');
assert.equal(divs[0].dy, 120);
assert.equal(divs[4].dy, -120);
raf.tick(50);
assert.equal(divs[0].dy, 108);
assert.equal(divs[4].dy, -60);
raf.tick(100);
assert.equal(divs[0].dy, 48);
assert.equal(divs[4].dy, 0);
raf.tick(150);
assert.equal(divs[0].dy, 0);
assert.equal(divs[4].dy, 0);
}
};

@ -0,0 +1,23 @@
{#each things as thing, i (thing.id)}
<div animate:flip="{delay: i * 10}">{thing.name}</div>
{/each}
<script>
export default {
animations: {
flip(node, animation, params) {
const dx = animation.from.left - animation.to.left;
const dy = animation.from.top - animation.to.top;
return {
delay: params.delay,
duration: 100,
tick: (t, u) => {
node.dx = u * dx;
node.dy = u * dy;
}
};
}
}
};
</script>
Loading…
Cancel
Save