Klima: Achievement-Tap-Tooltip (Touch hat keinen Hover)
Tap auf eine Erfolgs-Badge öffnet einen kleinen Tooltip mit Titel + Beschreibung. Verschwindet nach 4 s oder beim nächsten Tap außerhalb. Position bevorzugt unter der Badge, mit Fallback nach oben falls unten kein Platz.
This commit is contained in:
@@ -587,6 +587,23 @@
|
||||
}
|
||||
}
|
||||
|
||||
/* Achievement-Tooltip: title-Attribute öffnen sich auf Touch nicht; daher
|
||||
ein eigenes Tap-Popup mit Titel + Beschreibung. */
|
||||
.kw-ach-tooltip {
|
||||
position: fixed;
|
||||
z-index: 1500;
|
||||
max-width: 240px;
|
||||
background: var(--ggs-fjord-dark);
|
||||
color: var(--ggs-white);
|
||||
padding: 8px 12px;
|
||||
border-radius: var(--ggs-radius-sm);
|
||||
font-size: 13px;
|
||||
line-height: 1.4;
|
||||
box-shadow: var(--ggs-shadow-md);
|
||||
pointer-events: none;
|
||||
animation: ggs-fade-in 0.15s var(--ggs-ease) both;
|
||||
}
|
||||
|
||||
@keyframes kw-build-slidein {
|
||||
from { transform: translateX(100%); opacity: 0; }
|
||||
to { transform: translateX(0); opacity: 1; }
|
||||
@@ -1728,11 +1745,50 @@ function renderAchievements(force) {
|
||||
if (!has) classes.push('kw-ach-locked');
|
||||
el.className = classes.join(' ');
|
||||
el.title = a.title + (has ? ' — ' + a.desc : ' (noch nicht)');
|
||||
el.dataset.achTitle = a.title;
|
||||
el.dataset.achDesc = has ? a.desc : 'Noch nicht freigeschaltet.';
|
||||
el.textContent = has ? a.icon : '?';
|
||||
host.appendChild(el);
|
||||
});
|
||||
}
|
||||
|
||||
/* Achievement-Tap-Tooltip — title greift auf Touch nicht. Tap auf eine
|
||||
Badge zeigt einen kleinen schwarzen Tooltip mit Titel + Beschreibung,
|
||||
verschwindet nach 4 s oder beim nächsten Tap außerhalb. */
|
||||
let _achTooltip = null;
|
||||
let _achTooltipTimer = 0;
|
||||
function _hideAchTooltip() {
|
||||
if (_achTooltipTimer) { clearTimeout(_achTooltipTimer); _achTooltipTimer = 0; }
|
||||
if (_achTooltip) { _achTooltip.remove(); _achTooltip = null; }
|
||||
}
|
||||
document.addEventListener('click', (e) => {
|
||||
if (_achTooltip && !_achTooltip.contains(e.target) && !e.target.closest('.ggs-badge-earned')) {
|
||||
_hideAchTooltip();
|
||||
}
|
||||
const badge = e.target.closest('.ggs-badge-earned');
|
||||
if (!badge) return;
|
||||
const title = badge.dataset.achTitle || badge.title || '';
|
||||
const desc = badge.dataset.achDesc || '';
|
||||
if (!title) return;
|
||||
_hideAchTooltip();
|
||||
const t = document.createElement('div');
|
||||
t.className = 'kw-ach-tooltip';
|
||||
t.innerHTML = '<strong>' + title.replace(/[<>&]/g, c => ({'<':'<','>':'>','&':'&'}[c])) + '</strong>'
|
||||
+ (desc ? '<br>' + desc.replace(/[<>&]/g, c => ({'<':'<','>':'>','&':'&'}[c])) : '');
|
||||
document.body.appendChild(t);
|
||||
_achTooltip = t;
|
||||
const rect = badge.getBoundingClientRect();
|
||||
const tw = t.offsetWidth;
|
||||
const th = t.offsetHeight;
|
||||
const left = Math.max(8, Math.min(rect.left + rect.width / 2 - tw / 2, window.innerWidth - tw - 8));
|
||||
// Bevorzugt unter der Badge; falls dort kein Platz, nach oben.
|
||||
let top = rect.bottom + 8;
|
||||
if (top + th > window.innerHeight - 8) top = Math.max(8, rect.top - th - 8);
|
||||
t.style.left = left + 'px';
|
||||
t.style.top = top + 'px';
|
||||
_achTooltipTimer = setTimeout(_hideAchTooltip, 4000);
|
||||
});
|
||||
|
||||
/* ============================================================
|
||||
UI RENDERING
|
||||
============================================================ */
|
||||
|
||||
@@ -715,6 +715,23 @@
|
||||
}
|
||||
}
|
||||
|
||||
/* Achievement-Tooltip: title-Attribute öffnen sich auf Touch nicht; daher
|
||||
ein eigenes Tap-Popup mit Titel + Beschreibung. */
|
||||
.kw-ach-tooltip {
|
||||
position: fixed;
|
||||
z-index: 1500;
|
||||
max-width: 240px;
|
||||
background: var(--ggs-fjord-dark);
|
||||
color: var(--ggs-white);
|
||||
padding: 8px 12px;
|
||||
border-radius: var(--ggs-radius-sm);
|
||||
font-size: 13px;
|
||||
line-height: 1.4;
|
||||
box-shadow: var(--ggs-shadow-md);
|
||||
pointer-events: none;
|
||||
animation: ggs-fade-in 0.15s var(--ggs-ease) both;
|
||||
}
|
||||
|
||||
@keyframes kw-build-slidein {
|
||||
from { transform: translateX(100%); opacity: 0; }
|
||||
to { transform: translateX(0); opacity: 1; }
|
||||
@@ -2036,11 +2053,49 @@ function renderAchievements(force) {
|
||||
if (!has) classes.push('kw-ach-locked');
|
||||
el.className = classes.join(' ');
|
||||
el.title = a.title + (has ? ' — ' + a.desc : ' (noch nicht)');
|
||||
el.dataset.achTitle = a.title;
|
||||
el.dataset.achDesc = has ? a.desc : 'Noch nicht freigeschaltet.';
|
||||
el.textContent = has ? a.icon : '?';
|
||||
host.appendChild(el);
|
||||
});
|
||||
}
|
||||
|
||||
/* Achievement-Tap-Tooltip — title greift auf Touch nicht. Tap auf eine
|
||||
Badge zeigt einen kleinen schwarzen Tooltip mit Titel + Beschreibung,
|
||||
verschwindet nach 4 s oder beim nächsten Tap außerhalb. */
|
||||
let _achTooltip = null;
|
||||
let _achTooltipTimer = 0;
|
||||
function _hideAchTooltip() {
|
||||
if (_achTooltipTimer) { clearTimeout(_achTooltipTimer); _achTooltipTimer = 0; }
|
||||
if (_achTooltip) { _achTooltip.remove(); _achTooltip = null; }
|
||||
}
|
||||
document.addEventListener('click', (e) => {
|
||||
if (_achTooltip && !_achTooltip.contains(e.target) && !e.target.closest('.ggs-badge-earned')) {
|
||||
_hideAchTooltip();
|
||||
}
|
||||
const badge = e.target.closest('.ggs-badge-earned');
|
||||
if (!badge) return;
|
||||
const title = badge.dataset.achTitle || badge.title || '';
|
||||
const desc = badge.dataset.achDesc || '';
|
||||
if (!title) return;
|
||||
_hideAchTooltip();
|
||||
const t = document.createElement('div');
|
||||
t.className = 'kw-ach-tooltip';
|
||||
t.innerHTML = '<strong>' + title.replace(/[<>&]/g, c => ({'<':'<','>':'>','&':'&'}[c])) + '</strong>'
|
||||
+ (desc ? '<br>' + desc.replace(/[<>&]/g, c => ({'<':'<','>':'>','&':'&'}[c])) : '');
|
||||
document.body.appendChild(t);
|
||||
_achTooltip = t;
|
||||
const rect = badge.getBoundingClientRect();
|
||||
const tw = t.offsetWidth;
|
||||
const th = t.offsetHeight;
|
||||
const left = Math.max(8, Math.min(rect.left + rect.width / 2 - tw / 2, window.innerWidth - tw - 8));
|
||||
let top = rect.bottom + 8;
|
||||
if (top + th > window.innerHeight - 8) top = Math.max(8, rect.top - th - 8);
|
||||
t.style.left = left + 'px';
|
||||
t.style.top = top + 'px';
|
||||
_achTooltipTimer = setTimeout(_hideAchTooltip, 4000);
|
||||
});
|
||||
|
||||
/* ============================================================
|
||||
UI RENDERING
|
||||
============================================================ */
|
||||
|
||||
Reference in New Issue
Block a user