Skip to content

Instantly share code, notes, and snippets.

@buhrmi
Last active January 28, 2020 00:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save buhrmi/1e806fc4ab50e5cd5453ccfb90711e99 to your computer and use it in GitHub Desktop.
Save buhrmi/1e806fc4ab50e5cd5453ccfb90711e99 to your computer and use it in GitHub Desktop.
d3-powered crossfade for svelte
import { interpolateTransformCss as interpolate} from 'd3'
import { cubicOut } from 'svelte/easing'
export function crossfade({ fallback, ...defaults }) {
const to_receive = new Map();
const to_send = new Map();
function crossfade(fromNode, toNode, params) {
const { delay = 0, duration = d => Math.sqrt(d) * 30, easing = cubicOut } = Object.assign(Object.assign({}, defaults), params);
const toStyle = getComputedStyle(toNode);
const fromStyle = getComputedStyle(fromNode);
toNode.style.transform = 'none'
fromNode.style.transform = 'none'
const toRect = toNode.getBoundingClientRect();
const fromRect = fromNode.getBoundingClientRect();
toNode.style.transform = ''
fromNode.style.transform = ''
const dx = fromRect.left - toRect.left;
const dy = fromRect.top - toRect.top;
const d = Math.sqrt(dx * dx + dy * dy);
let fromTransform = fromStyle.transform === 'none' ? '' : fromStyle.transform
let toTransform = toStyle.transform === 'none' ? '' : toStyle.transform;
fromTransform = `translate(${dx}px, ${dy}px)` + fromTransform
toTransform = `translate(${0}px, ${0}px)` + toTransform
const interpolator = interpolate(fromTransform, toTransform)
const opacity = +toStyle.opacity;
return {
delay,
duration: typeof(duration) == 'function' ? duration(d) : duration,
easing,
css: (t) => `
opacity: ${t * opacity};
transform: ${interpolator(t)} ;
`
};
}
function transition(items, counterparts, intro) {
return (node, params) => {
items.set(params.key, {node});
return () => {
if (counterparts.has(params.key)) {
const { node: fromNode } = counterparts.get(params.key);
counterparts.delete(params.key);
return crossfade(fromNode, node, params);
}
// if the node is disappearing altogether
// (i.e. wasn't claimed by the other list)
// then we need to supply an outro
items.delete(params.key);
return fallback && fallback(node, params, intro);
};
};
}
return [
transition(to_send, to_receive, false),
transition(to_receive, to_send, true)
];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment