Placement plan: table outline with dimension labels + table layer toggle
This commit is contained in:
+18
-3
@@ -36,7 +36,7 @@ const PAPER = { A4: [210, 297], A3: [297, 420] };
|
|||||||
const MARGIN = 10; // mm printable margin
|
const MARGIN = 10; // mm printable margin
|
||||||
const OVERLAP = 10; // mm tile overlap for joining
|
const OVERLAP = 10; // mm tile overlap for joining
|
||||||
|
|
||||||
const opts = { scale: '1', paper: 'A4', anchors: true, buildings: true, spawns: true, paths: true };
|
const opts = { scale: '1', paper: 'A4', table: true, anchors: true, buildings: true, spawns: true, paths: true };
|
||||||
|
|
||||||
document.getElementById('controls').innerHTML = `
|
document.getElementById('controls').innerHTML = `
|
||||||
<label>Scale <select id="scale">
|
<label>Scale <select id="scale">
|
||||||
@@ -46,13 +46,13 @@ document.getElementById('controls').innerHTML = `
|
|||||||
<option value="fit">Fit one page</option>
|
<option value="fit">Fit one page</option>
|
||||||
</select></label>
|
</select></label>
|
||||||
<label>Paper <select id="paper"><option>A4</option><option>A3</option></select></label>
|
<label>Paper <select id="paper"><option>A4</option><option>A3</option></select></label>
|
||||||
${['anchors','buildings','spawns','paths'].map(k =>
|
${['table','anchors','buildings','spawns','paths'].map(k =>
|
||||||
`<label><input type="checkbox" id="ly-${k}" checked> ${k}</label>`).join('')}
|
`<label><input type="checkbox" id="ly-${k}" checked> ${k}</label>`).join('')}
|
||||||
<span style="flex:1"></span>
|
<span style="flex:1"></span>
|
||||||
<button class="primary" onclick="print()">Print…</button>
|
<button class="primary" onclick="print()">Print…</button>
|
||||||
<span id="pgCount" style="opacity:.7;font-size:.85rem"></span>`;
|
<span id="pgCount" style="opacity:.7;font-size:.85rem"></span>`;
|
||||||
['scale','paper'].forEach(id => document.getElementById(id).onchange = e => { opts[id] = e.target.value; build(); });
|
['scale','paper'].forEach(id => document.getElementById(id).onchange = e => { opts[id] = e.target.value; build(); });
|
||||||
['anchors','buildings','spawns','paths'].forEach(k =>
|
['table','anchors','buildings','spawns','paths'].forEach(k =>
|
||||||
document.getElementById('ly-' + k).onchange = e => { opts[k] = e.target.checked; build(); });
|
document.getElementById('ly-' + k).onchange = e => { opts[k] = e.target.checked; build(); });
|
||||||
|
|
||||||
// ---------- geometry ----------
|
// ---------- geometry ----------
|
||||||
@@ -62,6 +62,8 @@ function extent() {
|
|||||||
minX = Math.min(minX, x - pad); maxX = Math.max(maxX, x + pad);
|
minX = Math.min(minX, x - pad); maxX = Math.max(maxX, x + pad);
|
||||||
minZ = Math.min(minZ, z - pad); maxZ = Math.max(maxZ, z + pad);
|
minZ = Math.min(minZ, z - pad); maxZ = Math.max(maxZ, z + pad);
|
||||||
};
|
};
|
||||||
|
const t = scene.table;
|
||||||
|
if (t && t.show !== false) { eat(t.offsetX || 0, t.offsetZ || 0, 6); eat((t.offsetX || 0) + t.width, (t.offsetZ || 0) + t.depth, 6); }
|
||||||
for (const a of scene.anchors || []) eat(a.position[0], a.position[2]);
|
for (const a of scene.anchors || []) eat(a.position[0], a.position[2]);
|
||||||
for (const b of scene.buildings || []) eat(b.position[0], b.position[2], Math.max(b.size[0], b.size[2]) / 2 + 5);
|
for (const b of scene.buildings || []) eat(b.position[0], b.position[2], Math.max(b.size[0], b.size[2]) / 2 + 5);
|
||||||
for (const s of scene.spawns || []) eat(s.position[0], s.position[2]);
|
for (const s of scene.spawns || []) eat(s.position[0], s.position[2]);
|
||||||
@@ -101,6 +103,19 @@ function planSVG(ex, k) {
|
|||||||
<text y="-9.5" font-size="4" text-anchor="middle" font-weight="bold">N (+Z, back)</text>
|
<text y="-9.5" font-size="4" text-anchor="middle" font-weight="bold">N (+Z, back)</text>
|
||||||
<text y="13" font-size="3" text-anchor="middle" fill="#444">grid 10 cm</text></g>`;
|
<text y="13" font-size="3" text-anchor="middle" fill="#444">grid 10 cm</text></g>`;
|
||||||
|
|
||||||
|
if (opts.table && scene.table && scene.table.show !== false) {
|
||||||
|
const t = scene.table;
|
||||||
|
const x0 = t.offsetX || 0, z0 = t.offsetZ || 0;
|
||||||
|
const tx = X(x0), ty = Y(z0 + t.depth), tw = t.width * S, th = t.depth * S;
|
||||||
|
g += `<rect x="${px(tx)}" y="${px(ty)}" width="${px(tw)}" height="${px(th)}"
|
||||||
|
fill="none" stroke="#e67e00" stroke-width="0.7"/>`;
|
||||||
|
// dimension labels with arrows: width along the front (bottom) edge, depth along the left edge
|
||||||
|
g += `<text x="${px(tx + tw / 2)}" y="${px(ty + th + 5)}" font-size="4" text-anchor="middle" fill="#e67e00" font-weight="bold">← ${t.width} cm →</text>`;
|
||||||
|
g += `<text x="${px(tx - 3)}" y="${px(ty + th / 2)}" font-size="4" text-anchor="middle" fill="#e67e00" font-weight="bold"
|
||||||
|
transform="rotate(-90 ${px(tx - 3)} ${px(ty + th / 2)})">← ${t.depth} cm →</text>`;
|
||||||
|
g += `<text x="${px(tx + tw / 2)}" y="${px(ty - 2)}" font-size="3" text-anchor="middle" fill="#e67e00">TABLE ${t.width} × ${t.depth} cm — back edge (N)</text>`;
|
||||||
|
}
|
||||||
|
|
||||||
if (opts.paths) for (const p of scene.paths || []) {
|
if (opts.paths) for (const p of scene.paths || []) {
|
||||||
const pts = (p.points || []);
|
const pts = (p.points || []);
|
||||||
if (pts.length < 2) continue;
|
if (pts.length < 2) continue;
|
||||||
|
|||||||
Reference in New Issue
Block a user