/** * Mindmap Interaction Enhancement * Verbessert die Interaktion mit der Mindmap und steuert die Seitenleisten-Anzeige */ // Stellt sicher, dass das Dokument geladen ist, bevor Aktionen ausgeführt werden document.addEventListener('DOMContentLoaded', function() { console.log('Mindmap-Interaktionsverbesserungen werden initialisiert...'); // Auf das Laden der Mindmap warten document.addEventListener('mindmap-loaded', setupInteractionEnhancements); // Sofortiges Setup für statische Interaktionen setupStaticInteractions(); }); // Richtet grundlegende statische Interaktionen ein function setupStaticInteractions() { // Vergrößert die Mindmap auf Vollbildmodus, wenn der entsprechende Button geklickt wird const fullscreenBtn = document.getElementById('fullscreen-btn'); if (fullscreenBtn) { fullscreenBtn.addEventListener('click', toggleFullscreen); } // Initialisiert die Hover-Effekte für die Seitenleisten-Panels initializePanelEffects(); } // Richtet erweiterte Interaktionen mit der geladenen Mindmap ein function setupInteractionEnhancements() { console.log('Mindmap geladen - verbesserte Interaktionen werden eingerichtet'); // Zugriff auf die Mindmap-Instanz const mindmap = window.mindmapInstance; if (!mindmap) { console.warn('Mindmap-Instanz nicht gefunden!'); return; } // Verbesserte Zoom-Kontrollen setupZoomControls(mindmap); // Verhindere, dass der Browser die Seite scrollt, wenn über der Mindmap gezoomt wird preventScrollWhileZooming(); // Tastaturkürzel für Mindmap-Interaktionen setupKeyboardShortcuts(mindmap); // Verbesserte Touch-Gesten für mobile Geräte setupTouchInteractions(mindmap); } // Verhindert Browser-Scrolling während Zoom in der Mindmap function preventScrollWhileZooming() { const cyContainer = document.getElementById('cy'); if (cyContainer) { cyContainer.addEventListener('wheel', function(e) { if (e.ctrlKey || e.metaKey) { e.preventDefault(); // Verhindert Browser-Zoom bei Ctrl+Wheel } }, { passive: false }); } } // Richtet verbesserte Zoom-Kontrollen ein function setupZoomControls(mindmap) { const zoomInBtn = document.getElementById('zoom-in-btn'); const zoomOutBtn = document.getElementById('zoom-out-btn'); const resetZoomBtn = document.getElementById('reset-btn'); if (zoomInBtn) { zoomInBtn.addEventListener('click', function() { mindmap.svg.transition() .duration(300) .call(mindmap.svg.zoom().scaleBy, 1.4); }); } if (zoomOutBtn) { zoomOutBtn.addEventListener('click', function() { mindmap.svg.transition() .duration(300) .call(mindmap.svg.zoom().scaleBy, 0.7); }); } if (resetZoomBtn) { resetZoomBtn.addEventListener('click', function() { mindmap.svg.transition() .duration(500) .call(mindmap.svg.zoom().transform, d3.zoomIdentity); }); } } // Vollbildmodus umschalten function toggleFullscreen() { const mindmapContainer = document.querySelector('.mindmap-container'); if (!mindmapContainer) return; if (!document.fullscreenElement) { // Vollbildmodus aktivieren if (mindmapContainer.requestFullscreen) { mindmapContainer.requestFullscreen(); } else if (mindmapContainer.mozRequestFullScreen) { mindmapContainer.mozRequestFullScreen(); } else if (mindmapContainer.webkitRequestFullscreen) { mindmapContainer.webkitRequestFullscreen(); } else if (mindmapContainer.msRequestFullscreen) { mindmapContainer.msRequestFullscreen(); } // Icon ändern const fullscreenBtn = document.getElementById('fullscreen-btn'); if (fullscreenBtn) { const icon = fullscreenBtn.querySelector('i'); if (icon) { icon.className = 'fa-solid fa-compress'; } fullscreenBtn.setAttribute('title', 'Vollbildmodus beenden'); } } else { // Vollbildmodus beenden if (document.exitFullscreen) { document.exitFullscreen(); } else if (document.mozCancelFullScreen) { document.mozCancelFullScreen(); } else if (document.webkitExitFullscreen) { document.webkitExitFullscreen(); } else if (document.msExitFullscreen) { document.msExitFullscreen(); } // Icon zurücksetzen const fullscreenBtn = document.getElementById('fullscreen-btn'); if (fullscreenBtn) { const icon = fullscreenBtn.querySelector('i'); if (icon) { icon.className = 'fa-solid fa-expand'; } fullscreenBtn.setAttribute('title', 'Vollbildmodus'); } } } // Initialisiert Effekte für Seitenleisten-Panels function initializePanelEffects() { // Selektiert alle Panel-Elemente const panels = document.querySelectorAll('[data-sidebar]'); panels.forEach(panel => { // Hover-Effekt für Panels panel.addEventListener('mouseenter', function() { this.classList.add('hover'); }); panel.addEventListener('mouseleave', function() { this.classList.remove('hover'); }); }); } // Richtet Tastaturkürzel für Mindmap-Interaktionen ein function setupKeyboardShortcuts(mindmap) { document.addEventListener('keydown', function(e) { // Nur fortfahren, wenn keine Texteingabe im Fokus ist if (document.activeElement.tagName === 'INPUT' || document.activeElement.tagName === 'TEXTAREA' || document.activeElement.isContentEditable) { return; } // Tastaturkürzel switch(e.key) { case '+': case '=': // Einzoomen if (e.ctrlKey || e.metaKey) { e.preventDefault(); mindmap.svg.transition() .duration(300) .call(mindmap.svg.zoom().scaleBy, 1.2); } break; case '-': // Auszoomen if (e.ctrlKey || e.metaKey) { e.preventDefault(); mindmap.svg.transition() .duration(300) .call(mindmap.svg.zoom().scaleBy, 0.8); } break; case '0': // Zoom zurücksetzen if (e.ctrlKey || e.metaKey) { e.preventDefault(); mindmap.svg.transition() .duration(500) .call(mindmap.svg.zoom().transform, d3.zoomIdentity); } break; case 'f': // Vollbildmodus umschalten if (e.ctrlKey || e.metaKey) { e.preventDefault(); toggleFullscreen(); } break; case 'Escape': // Ausgewählten Knoten abwählen if (mindmap.selectedNode) { mindmap.nodeClicked(null, mindmap.selectedNode); } break; } }); } // Richtet Touch-Gesten für mobile Geräte ein function setupTouchInteractions(mindmap) { const cyContainer = document.getElementById('cy'); if (!cyContainer) return; let touchStartX, touchStartY; let touchStartTime; // Touch-Start-Event cyContainer.addEventListener('touchstart', function(e) { if (e.touches.length === 1) { touchStartX = e.touches[0].clientX; touchStartY = e.touches[0].clientY; touchStartTime = Date.now(); } }); // Touch-End-Event für Doppeltipp-Erkennung cyContainer.addEventListener('touchend', function(e) { if (Date.now() - touchStartTime < 300) { // Kurzer Tipp const doubleTapDelay = 300; const now = Date.now(); if (now - (window.lastTapTime || 0) < doubleTapDelay) { // Doppeltipp erkannt - Zentriere Ansicht mindmap.svg.transition() .duration(500) .call(mindmap.svg.zoom().transform, d3.zoomIdentity); e.preventDefault(); } window.lastTapTime = now; } }); }