Files
newbury-exhibit-v2/public/admin/print.html
T

57 lines
2.4 KiB
HTML

<!doctype html>
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1">
<title>Print Crests — Newbury Exhibit</title>
<style>
body { font-family:system-ui,sans-serif; margin:0; }
.sheet { display:flex; flex-wrap:wrap; gap:8mm; padding:10mm; }
.crest { text-align:center; page-break-inside:avoid; }
.crest canvas { image-rendering:pixelated; border:0.5mm solid #000; }
.crest .cap { font-size:9pt; margin-top:2mm; }
@media print { header { display:none } }
</style></head>
<body>
<div id="hdr"></div>
<div class="sheet" id="sheet"></div>
<script src="/vendor/cv.js"></script>
<script src="/vendor/svd.js"></script>
<script src="/vendor/posit1.js"></script>
<script src="/vendor/aruco.js"></script>
<script src="/vendor/dictionaries/aruco_4x4_1000.js"></script>
<script type="module">
import { requireAuth, styles, nav } from './admin.js';
document.getElementById('hdr').innerHTML = nav('print');
document.head.insertAdjacentHTML('beforeend', `<style>@media screen {${styles}}</style>`);
await requireAuth();
const scene = await (await fetch('/api/scene')).json();
const dic = new AR.Dictionary('ARUCO_4X4_1000');
const MM2PX = 96 / 25.4; // CSS px per mm
const sheet = document.getElementById('sheet');
for (const a of scene.anchors) {
const div = document.createElement('div');
div.className = 'crest';
const cv = document.createElement('canvas');
const bits = 4 + 2; // 4x4 payload + 1-cell black border each side
const px = Math.round(a.sizeMM * MM2PX);
cv.width = cv.height = bits * 10;
cv.style.width = cv.style.height = px + 'px';
const ctx = cv.getContext('2d');
ctx.fillStyle = '#000'; ctx.fillRect(0, 0, cv.width, cv.height);
const code = dic.codeList[a.markerId]; // 16-char '0'/'1' string, row-major
ctx.fillStyle = '#fff';
for (let y = 0; y < 4; y++) for (let x = 0; x < 4; x++) {
if (code[y * 4 + x] === '1') ctx.fillRect((x + 1) * 10, (y + 1) * 10, 10, 10);
}
div.appendChild(cv);
div.insertAdjacentHTML('beforeend',
`<div class="cap"><b>Crest #${a.markerId}</b> · ${a.sizeMM} mm · ${a.mount}` +
`${a.mount === 'wall' ? ` · yaw ${a.yawDeg}°` : ''}<br>` +
`pos ${a.position.map(v => v.toFixed(2)).join(', ')} m</div>`);
sheet.appendChild(div);
}
if (!scene.anchors.length) sheet.innerHTML = '<p style="padding:20px">No anchors in the scene yet — add some in the Layout editor.</p>';
</script>
</body></html>