unroll / tests /embed-host.html
SharpMeow's picture
Public API at window.unroll (schema, help, coverage test; ui and bench groups), embed mode with postMessage bridge and oEmbed, version 0.9.4 in About and API, ink_9um (9 µm) label and credit, Ink Bench hardening from the audit, hashchange without reload, capped test hooks
cc6b6d8
Raw History Blame Contribute Delete
2.83 kB
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Unroll embed test page</title>
<style>
body { font: 16px/1.5 system-ui, sans-serif; max-width: 860px; margin: 0 auto; padding: 24px; background: #f4efe6; color: #222; }
.frame { position: relative; width: 100%; aspect-ratio: 16 / 10; }
.frame iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; border-radius: 10px; }
.spacer { height: 1400px; }
pre { background: #fff; padding: 8px; max-height: 200px; overflow: auto; font-size: 12px; }
button { margin: 2px; }
</style>
</head>
<body>
<h1>A page that embeds Unroll</h1>
<p>Scroll this page with the wheel over the viewer: it scrolls until you click the viewer. The buttons below drive the viewer with postMessage.</p>
<!-- ?src=<viewer url> overrides the viewer, for local testing -->
<div class="frame"><iframe id="unroll" title="Unroll: a Herculaneum scroll in 3D" allow="fullscreen; clipboard-write" allowfullscreen loading="lazy"></iframe></div>
<p>
<button data-call='["setLayer","xray"]'>X-ray</button>
<button data-call='["setLayer","ink"]'>Published ink</button>
<button data-call='["setUnroll",0.5]'>Unroll half</button>
<button data-call='["play",true]'>Play</button>
<button data-call='["getState"]'>getState</button>
<button data-call='["destroy.tools"]'>Destroy tools</button>
</p>
<pre id="log"></pre>
<div class="spacer"></div>
<script>
var src = new URLSearchParams(location.search).get('src') || 'https://sharpmeow-unroll.static.hf.space/index.html?embed=1';
var frame = document.getElementById('unroll');
frame.src = src;
var viewerOrigin = new URL(src, location.href).origin;
var seq = 0, pending = {};
window.unrollEmbed = {
ready: null, events: [],
call: function (method) {
var args = Array.prototype.slice.call(arguments, 1), id = ++seq;
return new Promise(function (res) { pending[id] = res; frame.contentWindow.postMessage({ unroll: 1, id: id, method: method, args: args }, viewerOrigin); });
},
};
addEventListener('message', function (e) {
if (e.origin !== viewerOrigin || !e.data || e.data.unroll !== 1) return;
var d = e.data;
if (d.type === 'ready') { unrollEmbed.ready = d; unrollEmbed.call('subscribe', 'layer'); }
if (d.type === 'result' && pending[d.id]) { pending[d.id](d.result); delete pending[d.id]; }
if (d.type === 'event') unrollEmbed.events.push(d);
document.getElementById('log').textContent = JSON.stringify(d).slice(0, 300) + '\n' + document.getElementById('log').textContent.slice(0, 3000);
});
document.querySelectorAll('[data-call]').forEach(function (b) { b.onclick = function () { unrollEmbed.call.apply(null, JSON.parse(b.dataset.call)); }; });
</script>
</body>
</html>