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 {
|
@keyframes kw-build-slidein {
|
||||||
from { transform: translateX(100%); opacity: 0; }
|
from { transform: translateX(100%); opacity: 0; }
|
||||||
to { transform: translateX(0); opacity: 1; }
|
to { transform: translateX(0); opacity: 1; }
|
||||||
@@ -1728,11 +1745,50 @@ function renderAchievements(force) {
|
|||||||
if (!has) classes.push('kw-ach-locked');
|
if (!has) classes.push('kw-ach-locked');
|
||||||
el.className = classes.join(' ');
|
el.className = classes.join(' ');
|
||||||
el.title = a.title + (has ? ' — ' + a.desc : ' (noch nicht)');
|
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 : '?';
|
el.textContent = has ? a.icon : '?';
|
||||||
host.appendChild(el);
|
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
|
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 {
|
@keyframes kw-build-slidein {
|
||||||
from { transform: translateX(100%); opacity: 0; }
|
from { transform: translateX(100%); opacity: 0; }
|
||||||
to { transform: translateX(0); opacity: 1; }
|
to { transform: translateX(0); opacity: 1; }
|
||||||
@@ -2036,11 +2053,49 @@ function renderAchievements(force) {
|
|||||||
if (!has) classes.push('kw-ach-locked');
|
if (!has) classes.push('kw-ach-locked');
|
||||||
el.className = classes.join(' ');
|
el.className = classes.join(' ');
|
||||||
el.title = a.title + (has ? ' — ' + a.desc : ' (noch nicht)');
|
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 : '?';
|
el.textContent = has ? a.icon : '?';
|
||||||
host.appendChild(el);
|
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
|
UI RENDERING
|
||||||
============================================================ */
|
============================================================ */
|
||||||
|
|||||||
Reference in New Issue
Block a user