From 276af83cb77ca3399073edb99ede2558cc21797f Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Wed, 16 May 2018 00:06:55 -0400 Subject: [PATCH] support parameterised animations --- src/shared/animations.js | 20 ++++-- .../samples/animation-js-delay/_config.js | 62 +++++++++++++++++++ .../samples/animation-js-delay/main.html | 23 +++++++ 3 files changed, 100 insertions(+), 5 deletions(-) create mode 100644 test/runtime/samples/animation-js-delay/_config.js create mode 100644 test/runtime/samples/animation-js-delay/main.html diff --git a/src/shared/animations.js b/src/shared/animations.js index 8e05eb11f2..355c0254e7 100644 --- a/src/shared/animations.js +++ b/src/shared/animations.js @@ -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; } diff --git a/test/runtime/samples/animation-js-delay/_config.js b/test/runtime/samples/animation-js-delay/_config.js new file mode 100644 index 0000000000..eb0c7863e3 --- /dev/null +++ b/test/runtime/samples/animation-js-delay/_config.js @@ -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: ` +
a
+
b
+
c
+
d
+
e
+ `, + + 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); + } +}; \ No newline at end of file diff --git a/test/runtime/samples/animation-js-delay/main.html b/test/runtime/samples/animation-js-delay/main.html new file mode 100644 index 0000000000..5656f39700 --- /dev/null +++ b/test/runtime/samples/animation-js-delay/main.html @@ -0,0 +1,23 @@ +{#each things as thing, i (thing.id)} +
{thing.name}
+{/each} + + \ No newline at end of file