Files
website/static/js/mindmap-interaction.js

260 lines
7.6 KiB
JavaScript

/**
* 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;
}
});
}