treeToShapers = function (tree) {
const totalDepth = getDepth(tree);
const shapers = new Map();
function process(node, shaper, depth = 0) {
if (!shaper) {
shaper = (x, y) => y;
}
shapers.set(node.id, shaper);
const spreadPositions = stackChildren(node, true);
const stackedPositions = stackChildren(node, false);
const childDepth = depth + 1;
const fractionalChildDepth = childDepth / totalDepth;
const interpolatePositions = (childIdx, x) => {
let a = smoothstep(fractionalChildDepth, 1, x);
const s = 1 - spreadStrength;
a = a * (1 - s) + s;
return lerp(spreadPositions[childIdx], stackedPositions[childIdx], a);
};
for (let i = 0; i < node.children.length; i++) {
const childNode = node.children[i];
const childFraction = childNode.fraction / node.fraction;
const childShaper = (x, y) => {
const v = fancystep(fractionalChildDepth, 1, x) * childFraction;
y = v * (y - 0.5) + 0.5 + interpolatePositions(i, x);
return shaper(x, y);
};
process(childNode, childShaper, childDepth);
}
}
const pseudoRoot = {
id: "pseudoRoot",
fraction: 1,
children: [tree]
};
process(
pseudoRoot,
null,
-1
);
return shapers;
}