frontend: Zoom-Controls mit Auto-Collapse-Funktion
- Zoom-Controls collapse automatisch nach 3 Sekunden Inaktivität - Toggle-Button mit Lupe+Plus-Symbol zum Expandieren der Controls - Position weiter nach rechts-unten verschoben (6px) - Event-Delegation für zuverlässige Click-Erfassung - Lazy-Loading der DOM-Elemente für robuste Initialisierung Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Haiku 4.5
parent
154e3e92e2
commit
640cb95c27
@@ -140,11 +140,16 @@
|
|||||||
<div class="diagram"><ul class="tree" id="out"></ul></div>
|
<div class="diagram"><ul class="tree" id="out"></ul></div>
|
||||||
<div class="warnings" id="warn" role="status" aria-live="polite"></div>
|
<div class="warnings" id="warn" role="status" aria-live="polite"></div>
|
||||||
<div class="zoomctl" data-i18n-aria="zoomAria" aria-label="Zoom (Strg/Cmd + Mausrad)">
|
<div class="zoomctl" data-i18n-aria="zoomAria" aria-label="Zoom (Strg/Cmd + Mausrad)">
|
||||||
|
<button type="button" id="zoomToggle" class="zoomToggle" data-i18n-title="zoomTooltip" title="Zoom anzeigen" aria-label="Zoom anzeigen">
|
||||||
|
<svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="10" cy="10" r="6"/><path d="m15 15 4 4M10 7v6M7 10h6"/></svg>
|
||||||
|
</button>
|
||||||
|
<div class="zoomcontrols">
|
||||||
<button type="button" id="zoomOut" data-i18n-title="zoomOut" title="verkleinern">−</button>
|
<button type="button" id="zoomOut" data-i18n-title="zoomOut" title="verkleinern">−</button>
|
||||||
<button type="button" id="zoomReset" data-i18n-title="zoomReset" title="zurücksetzen">100 %</button>
|
<button type="button" id="zoomReset" data-i18n-title="zoomReset" title="zurücksetzen">100 %</button>
|
||||||
<button type="button" id="zoomIn" data-i18n-title="zoomIn" title="vergrößern">+</button>
|
<button type="button" id="zoomIn" data-i18n-title="zoomIn" title="vergrößern">+</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<footer class="site-footer"><a href="https://github.com/mhoennig/werkbaum" target="_blank" rel="noopener">Werkbaum</a> <a class="ver" href="https://github.com/mhoennig/werkbaum/commit/main" target="_blank" rel="noopener">1.0</a> – © 2026 <a href="https://michael.hoennig.de" target="_blank" rel="noopener">Michael Hönnig</a> · <span class="vibe" title="Fable 5 and Opus 4.8">Built with Claude Code</span> – <a href="../LICENSE" target="_blank" rel="noopener">License</a> · <a href="https://michael.hoennig.de/imprint.html" target="_blank" rel="noopener" data-i18n="imprint">Impressum</a> · <a id="privacyLink" href="https://michael.hoennig.de/datenschutzerklaerung.html" target="_blank" rel="noopener" data-i18n="privacy">Datenschutz</a></footer>
|
<footer class="site-footer"><a href="https://github.com/mhoennig/werkbaum" target="_blank" rel="noopener">Werkbaum</a> <a class="ver" href="https://github.com/mhoennig/werkbaum/commit/main" target="_blank" rel="noopener">1.0</a> – © 2026 <a href="https://michael.hoennig.de" target="_blank" rel="noopener">Michael Hönnig</a> · <span class="vibe" title="Fable 5 and Opus 4.8">Built with Claude Code</span> – <a href="../LICENSE" target="_blank" rel="noopener">License</a> · <a href="https://michael.hoennig.de/imprint.html" target="_blank" rel="noopener" data-i18n="imprint">Impressum</a> · <a id="privacyLink" href="https://michael.hoennig.de/datenschutzerklaerung.html" target="_blank" rel="noopener" data-i18n="privacy">Datenschutz</a></footer>
|
||||||
|
|||||||
@@ -443,22 +443,40 @@ gutter.addEventListener('dblclick', () => {
|
|||||||
/* CSS-`zoom` skaliert die Layout-Box, dadurch greifen die Scrollbalken
|
/* CSS-`zoom` skaliert die Layout-Box, dadurch greifen die Scrollbalken
|
||||||
des Diagramm-Containers korrekt (anders als transform: scale). */
|
des Diagramm-Containers korrekt (anders als transform: scale). */
|
||||||
const ZMIN = 0.3, ZMAX = 3, ZSTEP = 0.1;
|
const ZMIN = 0.3, ZMAX = 3, ZSTEP = 0.1;
|
||||||
|
const ZOOM_COLLAPSE_DELAY = 3000; /* 3 Sekunden */
|
||||||
let zoom = 1;
|
let zoom = 1;
|
||||||
|
let zoomCollapseTimeout;
|
||||||
|
|
||||||
|
function resetZoomCollapseTimeout(){
|
||||||
|
const zoomctl = document.querySelector('.zoomctl');
|
||||||
|
if(!zoomctl) return;
|
||||||
|
clearTimeout(zoomCollapseTimeout);
|
||||||
|
zoomctl.classList.remove('collapsed');
|
||||||
|
zoomCollapseTimeout = setTimeout(() => {
|
||||||
|
zoomctl.classList.add('collapsed');
|
||||||
|
}, ZOOM_COLLAPSE_DELAY);
|
||||||
|
}
|
||||||
|
|
||||||
function applyZoom(){
|
function applyZoom(){
|
||||||
zoom = Math.min(ZMAX, Math.max(ZMIN, Math.round(zoom * 100) / 100));
|
zoom = Math.min(ZMAX, Math.max(ZMIN, Math.round(zoom * 100) / 100));
|
||||||
out.style.zoom = zoom;
|
out.style.zoom = zoom;
|
||||||
document.getElementById('zoomReset').textContent = Math.round(zoom * 100) + ' %';
|
document.getElementById('zoomReset').textContent = Math.round(zoom * 100) + ' %';
|
||||||
|
resetZoomCollapseTimeout();
|
||||||
saveUI();
|
saveUI();
|
||||||
}
|
}
|
||||||
document.getElementById('zoomIn').addEventListener('click', () => { zoom += ZSTEP; applyZoom(); });
|
document.getElementById('zoomIn').addEventListener('click', () => { zoom += ZSTEP; applyZoom(); });
|
||||||
document.getElementById('zoomOut').addEventListener('click', () => { zoom -= ZSTEP; applyZoom(); });
|
document.getElementById('zoomOut').addEventListener('click', () => { zoom -= ZSTEP; applyZoom(); });
|
||||||
document.getElementById('zoomReset').addEventListener('click', () => { zoom = 1; applyZoom(); });
|
document.getElementById('zoomReset').addEventListener('click', () => { zoom = 1; applyZoom(); });
|
||||||
|
document.querySelector('.zoomctl').addEventListener('click', (e) => {
|
||||||
|
if(e.target.closest('#zoomToggle')) resetZoomCollapseTimeout();
|
||||||
|
});
|
||||||
diagramEl.addEventListener('wheel', e => {
|
diagramEl.addEventListener('wheel', e => {
|
||||||
if(!(e.ctrlKey || e.metaKey)) return; /* Strg/Cmd + Mausrad zoomt */
|
if(!(e.ctrlKey || e.metaKey)) return; /* Strg/Cmd + Mausrad zoomt */
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
zoom += (e.deltaY < 0 ? ZSTEP : -ZSTEP);
|
zoom += (e.deltaY < 0 ? ZSTEP : -ZSTEP);
|
||||||
applyZoom();
|
applyZoom();
|
||||||
}, {passive:false});
|
}, {passive:false});
|
||||||
|
resetZoomCollapseTimeout(); /* Initialer Timeout beim Laden */
|
||||||
|
|
||||||
const showc = document.getElementById('showc');
|
const showc = document.getElementById('showc');
|
||||||
function discardedShown(){ return showc.getAttribute('aria-pressed') === 'true'; }
|
function discardedShown(){ return showc.getAttribute('aria-pressed') === 'true'; }
|
||||||
|
|||||||
@@ -343,7 +343,7 @@
|
|||||||
|
|
||||||
/* Zoom-Steuerung: schwebt unten rechts über dem Diagramm. */
|
/* Zoom-Steuerung: schwebt unten rechts über dem Diagramm. */
|
||||||
.zoomctl{
|
.zoomctl{
|
||||||
position:absolute;right:14px;bottom:14px;z-index:5;
|
position:absolute;right:6px;bottom:6px;z-index:5;
|
||||||
display:inline-flex;align-items:center;gap:2px;padding:2px;
|
display:inline-flex;align-items:center;gap:2px;padding:2px;
|
||||||
background:var(--card);border:1px solid rgba(36,52,71,.18);
|
background:var(--card);border:1px solid rgba(36,52,71,.18);
|
||||||
border-radius:8px;box-shadow:0 1px 4px rgba(36,52,71,.14);
|
border-radius:8px;box-shadow:0 1px 4px rgba(36,52,71,.14);
|
||||||
@@ -355,6 +355,10 @@
|
|||||||
}
|
}
|
||||||
#zoomReset{min-width:48px;font-size:.72rem}
|
#zoomReset{min-width:48px;font-size:.72rem}
|
||||||
.zoomctl button:hover{background:var(--paper);color:var(--or)}
|
.zoomctl button:hover{background:var(--paper);color:var(--or)}
|
||||||
|
.zoomToggle{display:none;padding:6px}
|
||||||
|
.zoomToggle svg{width:20px;height:20px}
|
||||||
|
.zoomctl.collapsed .zoomToggle{display:block}
|
||||||
|
.zoomctl.collapsed .zoomcontrols{display:none}
|
||||||
.panel.collapsed .zoomctl{display:none}
|
.panel.collapsed .zoomctl{display:none}
|
||||||
|
|
||||||
/* ---------- Baum ---------- */
|
/* ---------- Baum ---------- */
|
||||||
|
|||||||
Reference in New Issue
Block a user