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;
|
||||
|
||||
Reference in New Issue
Block a user