natus tooltip: fix portal placement + viewport clamping + SVG sign icon
- Move #id_natus_tooltip out of #id_applets_container (container-type: inline-size breaks position:fixed) → add to home.html alongside #id_tooltip_portal - Move #id_natus_tooltip out of .natus-modal-wrap (transform breaks position:fixed) → place as sibling of .natus-overlay in room.html - Add _positionTooltip() helper in natus-wheel.js: flips tooltip to left of cursor when it would overflow right edge; clamps both axes - Replace hardcoded 280px in dashboard.js palette tooltip with measured offsetWidth; add left-edge floor (Math.max margin) - Planet tooltip format: @14.0° Capricorn (<svg-icon>) using preloaded _signPaths; falls back to unicode symbol if not yet loaded - Add .tt-sign-icon SCSS: fill:currentColor, vertical-align:middle Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -49,8 +49,10 @@ const bindPaletteSwatches = () => {
|
||||
portal.style.display = 'block';
|
||||
portal.style.position = 'fixed';
|
||||
portal.style.top = `${rect.bottom + 8}px`;
|
||||
portal.style.left = `${Math.min(rect.left, window.innerWidth - 280)}px`;
|
||||
portal.style.zIndex = '9999';
|
||||
const margin = 8;
|
||||
const ttW = portal.offsetWidth;
|
||||
portal.style.left = `${Math.max(margin, Math.min(rect.left, window.innerWidth - ttW - margin))}px`;
|
||||
}
|
||||
|
||||
function hideTooltip() {
|
||||
|
||||
@@ -113,6 +113,27 @@ const NatusWheel = (() => {
|
||||
return ((ecliptic % 360) + 360) % 360 % 30;
|
||||
}
|
||||
|
||||
/** Inline SVG for a zodiac sign, sized to 1em, using current text colour. */
|
||||
function _signIconSvg(signName) {
|
||||
const d = _signPaths[signName];
|
||||
if (!d) return '';
|
||||
return `<svg viewBox="0 0 640 640" width="1em" height="1em" class="tt-sign-icon" aria-hidden="true"><path d="${d}"/></svg>`;
|
||||
}
|
||||
|
||||
/** Position tooltip near cursor, clamped so it never overflows the viewport. */
|
||||
function _positionTooltip(tooltip, event) {
|
||||
const margin = 8;
|
||||
tooltip.style.display = 'block';
|
||||
const ttW = tooltip.offsetWidth;
|
||||
const ttH = tooltip.offsetHeight;
|
||||
let left = event.clientX + 14;
|
||||
let top = event.clientY - 10;
|
||||
if (left + ttW + margin > window.innerWidth) left = event.clientX - ttW - 14;
|
||||
if (top + ttH + margin > window.innerHeight) top = event.clientY - ttH - 10;
|
||||
tooltip.style.left = Math.max(margin, left) + 'px';
|
||||
tooltip.style.top = Math.max(margin, top) + 'px';
|
||||
}
|
||||
|
||||
function _layout(svgEl) {
|
||||
const rect = svgEl.getBoundingClientRect();
|
||||
const size = Math.min(rect.width || 400, rect.height || 400);
|
||||
@@ -295,17 +316,15 @@ const NatusWheel = (() => {
|
||||
d3.select(this).classed('nw-planet--hover', true);
|
||||
const tooltip = document.getElementById('id_natus_tooltip');
|
||||
if (!tooltip) return;
|
||||
const sym = PLANET_SYMBOLS[name] || name[0];
|
||||
const sym = PLANET_SYMBOLS[name] || name[0];
|
||||
const signData = SIGNS.find(s => s.name === pdata.sign) || {};
|
||||
const signSym = signData.symbol || '';
|
||||
const inDeg = _inSignDeg(pdata.degree).toFixed(1);
|
||||
const rx = pdata.retrograde ? ' ℞' : '';
|
||||
const inDeg = _inSignDeg(pdata.degree).toFixed(1);
|
||||
const rx = pdata.retrograde ? ' ℞' : '';
|
||||
const icon = _signIconSvg(pdata.sign) || signData.symbol || '';
|
||||
tooltip.innerHTML =
|
||||
`<div class="tt-title tt-title--${el}">${name} (${sym})</div>` +
|
||||
`<div class="tt-description">${inDeg}° ${pdata.sign} ${signSym}${rx}</div>`;
|
||||
tooltip.style.left = (event.clientX + 14) + 'px';
|
||||
tooltip.style.top = (event.clientY - 10) + 'px';
|
||||
tooltip.style.display = 'block';
|
||||
`<div class="tt-description">@${inDeg}° ${pdata.sign} (${icon})${rx}</div>`;
|
||||
_positionTooltip(tooltip, event);
|
||||
})
|
||||
.on('mouseout', function (event) {
|
||||
// Ignore mouseout when moving between children of this group
|
||||
@@ -427,9 +446,7 @@ const NatusWheel = (() => {
|
||||
tooltip.innerHTML =
|
||||
`<div class="tt-title tt-title--el-${elKey}">[${info.abbr}] ${info.name}</div>` +
|
||||
`<div class="tt-description">${info.classical} · ${count} (${pct}%)</div>`;
|
||||
tooltip.style.left = (event.clientX + 14) + 'px';
|
||||
tooltip.style.top = (event.clientY - 10) + 'px';
|
||||
tooltip.style.display = 'block';
|
||||
_positionTooltip(tooltip, event);
|
||||
})
|
||||
.on('mouseout', function (event) {
|
||||
if (sliceGroup.node().contains(event.relatedTarget)) return;
|
||||
|
||||
@@ -449,7 +449,9 @@ html.natus-open .natus-modal-wrap {
|
||||
.nw-element--air { fill: rgba(var(--priCy, 64, 144, 176), 0.92); stroke: rgba(var(--quaUser), 1); stroke-width: 0.5px; }
|
||||
.nw-element--water { fill: rgba(var(--priId, 80, 80, 160), 0.92); stroke: rgba(var(--quaUser), 1); stroke-width: 0.5px; }
|
||||
|
||||
// ── Planet hover tooltip — uses .tt base styles; overrides position + z ───────
|
||||
// ── Planet hover tooltip — must live outside any ancestor with transform or
|
||||
// container-type (both break position:fixed). Placed as a direct sibling of
|
||||
// .natus-overlay in room.html; alongside #id_tooltip_portal in home.html. ──
|
||||
|
||||
#id_natus_tooltip {
|
||||
position: fixed;
|
||||
@@ -459,6 +461,7 @@ html.natus-open .natus-modal-wrap {
|
||||
|
||||
.tt-title { font-size: 1rem; font-weight: 700; }
|
||||
.tt-description { font-size: 0.75rem; }
|
||||
.tt-sign-icon { fill: currentColor; vertical-align: middle; margin-bottom: 0.1em; }
|
||||
|
||||
// Planet title colors — senary (brightest) tier on dark palettes
|
||||
.tt-title--au { color: rgba(var(--sixAu), 1); } // Sun
|
||||
|
||||
@@ -74,7 +74,6 @@
|
||||
{% endif %}
|
||||
</section>
|
||||
|
||||
<div id="id_natus_tooltip" class="tt" style="display:none;"></div>
|
||||
<script src="{% static 'apps/gameboard/d3.min.js' %}"></script>
|
||||
<script src="{% static 'apps/gameboard/natus-wheel.js' %}"></script>
|
||||
<script>
|
||||
|
||||
@@ -21,5 +21,6 @@
|
||||
{% include "apps/applets/_partials/_gear.html" with menu_id="id_dash_applet_menu" %}
|
||||
</div>
|
||||
<div id="id_tooltip_portal" class="token-tooltip" style="display:none;"></div>
|
||||
<div id="id_natus_tooltip" class="tt" style="display:none;"></div>
|
||||
{% endif %}
|
||||
{% endblock content %}
|
||||
|
||||
@@ -99,9 +99,6 @@
|
||||
</div>{# /.natus-modal-wrap #}
|
||||
</div>{# /.natus-overlay #}
|
||||
|
||||
{# Planet hover tooltip — position:fixed so it escapes overflow:hidden on the modal #}
|
||||
<div id="id_natus_tooltip" class="tt" style="display:none;"></div>
|
||||
|
||||
<script src="{% static 'apps/gameboard/d3.min.js' %}"></script>
|
||||
<script src="{% static 'apps/gameboard/natus-wheel.js' %}"></script>
|
||||
<script>
|
||||
|
||||
@@ -71,6 +71,10 @@
|
||||
{% if room.table_status == "SKY_SELECT" %}
|
||||
{% include "apps/gameboard/_partials/_natus_overlay.html" %}
|
||||
{% endif %}
|
||||
{# Natus tooltip: sibling of .natus-overlay, not inside .natus-modal-wrap (which has transform) #}
|
||||
{% if room.table_status == "SKY_SELECT" %}
|
||||
<div id="id_natus_tooltip" class="tt" style="display:none;"></div>
|
||||
{% endif %}
|
||||
|
||||
{% if room.gate_status != "RENEWAL_DUE" and room.table_status != "SIG_SELECT" %}
|
||||
{% include "apps/gameboard/_partials/_table_positions.html" %}
|
||||
|
||||
Reference in New Issue
Block a user