.stage{width:96%;height:90%}
.tree{width:100%;height:100%}
.edge{stroke:var(--line);stroke-width:1.5;fill:none;stroke-dasharray:120;stroke-dashoffset:120;transition:stroke-dashoffset .6s ease}
.edge.on{stroke-dashoffset:0}
.node{fill:var(--surface);stroke:var(--line);stroke-width:1.5;opacity:0;transition:opacity .4s}
.node.root{fill:var(--accent);stroke:none}
.node.on{opacity:1}
text{font:700 9px sans-serif;fill:var(--fg);text-anchor:middle;opacity:0;transition:opacity .4s}
text.on{opacity:1}
const edgesG = document.getElementById('edges');
const nodesG = document.getElementById('nodes');
const NS = 'http://www.w3.org/2000/svg';
const root = { x: 200, y: 20 };
const mids = [{ x: 80, y: 90 }, { x: 200, y: 90 }, { x: 320, y: 90 }];
const leaves = [
{ x: 40, y: 165, p: 0 }, { x: 120, y: 165, p: 0 },
{ x: 200, y: 165, p: 1 },
{ x: 280, y: 165, p: 2 }, { x: 360, y: 165, p: 2 },
];
function edge(a, b) {
const p = document.createElementNS(NS, 'path');
p.setAttribute('class', 'edge');
p.setAttribute('d', 'M' + a.x + ' ' + a.y + ' L' + b.x + ' ' + b.y);
edgesG.appendChild(p);
return p;
}
function node(pt, cls) {
const c = document.createElementNS(NS, 'circle');
c.setAttribute('class', 'node ' + (cls || ''));
c.setAttribute('cx', pt.x); c.setAttribute('cy', pt.y); c.setAttribute('r', 9);
nodesG.appendChild(c);
return c;
}
const rootNode = node(root, 'root');
const midEdges = mids.map((m) => edge(root, m));
const midNodes = mids.map((m) => node(m));
const leafEdges = leaves.map((l) => edge(mids[l.p], l));
const leafNodes = leaves.map((l) => node(l));
rootNode.classList.add('on');
function reveal(list) { list.forEach((el) => el.classList.add('on')); }
function hide(list) { list.forEach((el) => el.classList.remove('on')); }
async function loop() {
for (;;) {
reveal(midEdges); reveal(midNodes);
await new Promise((r) => setTimeout(r, 700));
reveal(leafEdges); reveal(leafNodes);
await new Promise((r) => setTimeout(r, 1800));
hide(leafEdges); hide(leafNodes); hide(midEdges); hide(midNodes);
await new Promise((r) => setTimeout(r, 500));
}
}
loop();