// Text-to-Scene gallery (scripts/t2s_gallery.py): a viewer for the renders, stepping through one agent's four views // of a scene, and "Full brief" for the scene briefs. Without it, every thumbnail still links to its full render. (() => { const links = [...document.querySelectorAll('a.gimg')]; if (links.length) { const box = document.createElement('div'); box.className = 'gbox'; box.hidden = true; box.setAttribute('role', 'dialog'); box.setAttribute('aria-modal', 'true'); box.setAttribute('aria-label', 'Render viewer'); box.innerHTML = '' + '' + '
' + ''; document.body.append(box); const img = box.querySelector('img'), cap = box.querySelector('.gbox-cap'), buttons = [...box.querySelectorAll('button')]; let group = [], i = 0, opener = null; const show = k => { i = (k + group.length) % group.length; const a = group[i]; img.src = a.href; img.alt = a.dataset.caption; cap.textContent = a.dataset.caption; new Image().src = group[(i + 1) % group.length].href; // the next view, ahead of the click }; const open = a => { group = links.filter(x => x.dataset.group === a.dataset.group); opener = a; show(group.indexOf(a)); box.hidden = false; document.body.style.overflow = 'hidden'; buttons[0].focus(); }; const close = () => { box.hidden = true; img.removeAttribute('src'); document.body.style.overflow = ''; if (opener) opener.focus(); }; links.forEach(a => a.addEventListener('click', ev => { if (ev.metaKey || ev.ctrlKey || ev.shiftKey || ev.altKey || ev.button) return; ev.preventDefault(); open(a); })); buttons[0].addEventListener('click', close); buttons[1].addEventListener('click', () => show(i - 1)); buttons[2].addEventListener('click', () => show(i + 1)); box.addEventListener('click', ev => { if (ev.target === box) close(); }); document.addEventListener('keydown', ev => { if (box.hidden) return; if (ev.key === 'Escape') close(); else if (ev.key === 'ArrowLeft') show(i - 1); else if (ev.key === 'ArrowRight') show(i + 1); else if (ev.key === 'Tab') { // keep focus on the viewer's three buttons const k = buttons.indexOf(document.activeElement); ev.preventDefault(); buttons[(k + (ev.shiftKey ? -1 : 1) + buttons.length) % buttons.length].focus(); } }); } // briefs: two lines, and a "Full brief" button where that hides text const fit = () => document.querySelectorAll('.gal-brief').forEach(p => { let b = p.nextElementSibling; if (!b || !b.classList.contains('gal-brief-btn')) { b = Object.assign(document.createElement('button'), {type: 'button', className: 'gal-brief-btn'}); b.addEventListener('click', () => { b.textContent = p.classList.toggle('open') ? 'Less' : 'Full brief'; }); p.after(b); } if (p.classList.contains('open')) return; b.textContent = 'Full brief'; b.hidden = p.scrollHeight <= p.clientHeight + 1; }); (document.fonts ? document.fonts.ready : Promise.resolve()).then(fit); let t; addEventListener('resize', () => { clearTimeout(t); t = setTimeout(fit, 150); }); })();