diff --git a/web/app.js b/web/app.js index 02e86fc..e757144 100644 --- a/web/app.js +++ b/web/app.js @@ -1779,6 +1779,7 @@ */ function reserveFloatText() { if (!state.options.text) return; + openArea(); for (const float of state.floats) { float.box = null; if (!float.featured) continue; @@ -1798,6 +1799,9 @@ for (const flip of [1, -1]) { const side = float.side * flip; const box = calloutBox(point, side, float.rise, float.width); + // Words under a panel or off the edge are words nobody reads. + if (box.x < open.left || box.x + box.w > open.right) continue; + if (box.y < open.top || box.y + box.h > open.bottom) continue; if (!claim(box.x, box.y, box.w, box.h)) continue; float.side = side; float.box = box; @@ -1816,6 +1820,20 @@ } } + /** The part of the screen no panel or bar covers, in screen pixels. */ + const open = { left: 0, top: 0, right: 0, bottom: 0 }; + const detailRoot = document.getElementById("detail-root"); + + /** Measures `open` for this frame. */ + function openArea() { + const wide = view.width > 1100; + const detail = detailRoot.firstElementChild; + open.left = wide && detail && !detail.hidden ? 352 : 6; + open.top = 52; + open.right = view.width - (wide ? 346 : 6); + open.bottom = view.height - (wide ? 54 : 6); + } + /** Callouts are set in the plate's monospace: a name over a line. */ const CALLOUT_FONT = `12px ${Look.MONO}`; const CALLOUT_NAME_FONT = `600 10px ${Look.MONO}`; @@ -2919,11 +2937,11 @@ const point = toScreen(float.agent.rx, float.agent.ry); if (onScreen(point, 60)) { const t = age / PING_TTL; - const open = still ? 0.3 : 1 - (1 - t) ** 3; + const spread = still ? 0.3 : 1 - (1 - t) ** 3; ctx.strokeStyle = `rgba(255, 252, 242, ${(1 - t) ** 1.6 * 0.85 * emphasised})`; ctx.lineWidth = 1.25; ctx.beginPath(); - ctx.arc(point.x, point.y, 6 + open * 30, 0, Math.PI * 2); + ctx.arc(point.x, point.y, 6 + spread * 30, 0, Math.PI * 2); ctx.stroke(); } }