{ class Waiter { constructor() { this.promise = new Promise((resolve) => { this.resolve = resolve; }); } } async function getSVGDocument(elem) { const data = elem.data; elem.data = ''; elem.data = data; const waiter = new Waiter(); elem.addEventListener('load', waiter.resolve); await waiter.promise; return elem.getSVGDocument(); } const diagrams = { lookup: { async init(elem) { const svg = await getSVGDocument(elem); const partsByName = {}; [ '[id$=-Input]', '[id$=-Output]', '[id$=-Result]', ].forEach((selector) => { [...svg.querySelectorAll('[id^=Effect]')].forEach((elem) => { // because affinity designer doesn't export blend modes (T_T) // and because I'd prefer not to have to manually fix things as I edit. // I suppose I could add a build process. elem.style.mixBlendMode = elem.id.split('-')[1]; }); [...svg.querySelectorAll(selector)].forEach((elem) => { const [name, type] = elem.id.split('-'); partsByName[name] = partsByName[name] || {}; partsByName[name][type] = elem; elem.style.visibility = 'hidden'; }); }); const parts = Object.keys(partsByName).sort().map(k => partsByName[k]); let ndx = 0; let step = 0; let delay = 0; setInterval(() => { const part = parts[ndx]; switch (step) { case 0: part.Input.style.visibility = ''; ++step; break; case 1: part.Output.style.visibility = ''; ++step; break; case 2: part.Result.style.visibility = ''; ++step; break; case 3: part.Input.style.visibility = 'hidden'; part.Output.style.visibility = 'hidden'; ndx = (ndx + 1) % parts.length; if (ndx === 0) { step = 4; delay = 4; } else { step = 0; } break; case 4: --delay; if (delay <= 0) { for (const part of parts) { for (const elem of Object.values(part)) { elem.style.visibility = 'hidden'; } } step = 0; } break; } }, 500); }, }, }; [...document.querySelectorAll('[data-diagram]')].forEach(createDiagram); function createDiagram(base) { const name = base.dataset.diagram; const info = diagrams[name]; if (!info) { throw new Error(`no diagram ${name}`); } info.init(base); } }