Skip to content

Commit 394e3e9

Browse files
committed
add crossfade and flip functions (sveltejs#2241)
1 parent c2413ae commit 394e3e9

File tree

4 files changed

+86
-1
lines changed

4 files changed

+86
-1
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ node_modules
1010
/easing.js
1111
/motion.*
1212
/transition.js
13+
/animate.js
1314
/scratch/
1415
/coverage/
1516
/coverage.lcov/

animate.mjs

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { cubicOut } from './easing';
2+
import { is_function } from './internal';
3+
4+
export function flip(node, animation, params) {
5+
const style = getComputedStyle(node);
6+
const transform = style.transform === 'none' ? '' : style.transform;
7+
8+
const dx = animation.from.left - animation.to.left;
9+
const dy = animation.from.top - animation.to.top;
10+
11+
const d = Math.sqrt(dx * dx + dy * dy);
12+
13+
const {
14+
delay = 0,
15+
duration = d => Math.sqrt(d) * 120,
16+
easing = cubicOut
17+
} = params;
18+
19+
return {
20+
delay,
21+
duration: is_function(duration) ? duration(d) : duration,
22+
easing,
23+
css: (t, u) => `transform: ${transform} translate(${u * dx}px, ${u * dy}px);`
24+
};
25+
}

rollup.config.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ export default [
8888
},
8989

9090
// everything else
91-
...['index', 'store', 'easing', 'transition'].map(name => ({
91+
...['index', 'store', 'easing', 'transition', 'animate'].map(name => ({
9292
input: `${name}.mjs`,
9393
output: {
9494
file: `${name}.js`,

transition.mjs

+59
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { cubicOut, cubicInOut } from './easing';
2+
import { assign, is_function } from './internal';
23

34
export function fade(node, {
45
delay = 0,
@@ -79,4 +80,62 @@ export function draw(node, {
7980
easing,
8081
css: (t, u) => `stroke-dasharray: ${t * len} ${u * len}`
8182
};
83+
}
84+
85+
export function crossfade({ fallback, ...defaults }) {
86+
let to_receive = new Map();
87+
let to_send = new Map();
88+
89+
function crossfade(from, node, params) {
90+
const {
91+
delay = 0,
92+
duration = d => Math.sqrt(d) * 30,
93+
easing = cubicOut
94+
} = assign(assign({}, defaults), params);
95+
96+
const to = node.getBoundingClientRect();
97+
const dx = from.left - to.left;
98+
const dy = from.top - to.top;
99+
100+
const style = getComputedStyle(node);
101+
const transform = style.transform === 'none' ? '' : style.transform;
102+
103+
return {
104+
delay,
105+
duration: is_function(duration) ? duration(d) : duration,
106+
easing,
107+
css: (t, u) => `
108+
opacity: ${t};
109+
transform: ${transform} translate(${u * dx}px,${u * dy}px);
110+
`
111+
};
112+
}
113+
114+
function transition(items, counterparts, intro) {
115+
return (node, params) => {
116+
items.set(params.key, {
117+
rect: node.getBoundingClientRect()
118+
});
119+
120+
return () => {
121+
if (counterparts.has(params.key)) {
122+
const { rect } = counterparts.get(params.key);
123+
counterparts.delete(params.key);
124+
125+
return crossfade(rect, node, params);
126+
}
127+
128+
// if the node is disappearing altogether
129+
// (i.e. wasn't claimed by the other list)
130+
// then we need to supply an outro
131+
items.delete(params.key);
132+
return fallback(node, params, intro);
133+
};
134+
};
135+
}
136+
137+
return [
138+
transition(to_send, to_receive, false),
139+
transition(to_receive, to_send, true)
140+
];
82141
}

0 commit comments

Comments
 (0)