Update requirements and enhance mindmap UI: Comment out Pillow dependency, add network background script, and implement new styles and animations for improved visual effects in the mindmap template.

This commit is contained in:
2025-04-25 21:30:35 +01:00
parent 84b492d8d2
commit ab280b55af
10 changed files with 636 additions and 105 deletions

69
ANLEITUNG.md Normal file
View File

@@ -0,0 +1,69 @@
# Anleitung: Animierter Netzwerk-Hintergrund
Diese Anleitung erklärt, wie Sie ein Netzwerk-Bild als animierten Hintergrund für die gesamte Website einrichten können.
## Option 1: Manuelle Installation
1. Kopieren Sie das gewünschte Netzwerk-Bild (z.B. `d2efd014-1325-471f-b9a7-90d025eb81d6.png`) in die Datei `website/static/network-bg.jpg`.
Sie können dafür das beiliegende Batch-Skript verwenden:
```
copy-network-image.bat d2efd014-1325-471f-b9a7-90d025eb81d6.png
```
2. Starten Sie den Flask-Server mit dem folgenden Befehl:
```
python start-flask-server.py
```
3. Öffnen Sie die Website unter http://127.0.0.1:5000/
## Anpassung der Animation
Sie können die Animation des Netzwerk-Hintergrunds anpassen, indem Sie die Datei `website/static/network-background.js` bearbeiten. Hier sind die wichtigsten Parameter:
```javascript
let animationSpeed = 0.0005; // Geschwindigkeit der Rotation
let scaleSpeed = 0.0002; // Geschwindigkeit der Skalierung
let opacitySpeed = 0.0003; // Geschwindigkeit der Transparenzänderung
```
## Animation der Mindmap-Verbindungen
Die Verbindungen zwischen den Knoten in der Mindmap werden jetzt mit einer fließenden Animation dargestellt. Diese Animationen verbessern die Sichtbarkeit der Zusammenhänge und machen die Interaktion mit der Karte intuitiver.
### Funktionen:
1. **Animierte Linien**: Die Verbindungslinien zwischen den Knoten bewegen sich in einem fließenden Muster.
2. **Hervorhebung bei Hover**: Beim Überfahren eines Knotens oder einer Verbindung mit der Maus werden diese hervorgehoben.
3. **Kategorien-Beziehungen**: Die visuellen Verbindungen zwischen den Kategorien sind jetzt deutlicher erkennbar.
## Position des Auswahlfelds
Das Auswahlfeld auf der Karte wurde weiter nach links verschoben, sodass es vollständig sichtbar ist, wenn keine Auswahl getroffen wurde. Die Größe wurde ebenfalls angepasst, um die Lesbarkeit zu verbessern.
## Wiederherstellung des ursprünglichen Hintergrunds (optional)
Wenn Sie zum ursprünglichen Sternenhintergrund zurückkehren möchten, müssen Sie folgende Änderungen vornehmen:
1. Bearbeiten Sie die Datei `website/templates/base.html` und ersetzen Sie:
```html
<!-- Network Background Script -->
<script src="{{ url_for('static', filename='network-background.js') }}"></script>
```
mit:
```html
<!-- Three.js für den Sternenhintergrund -->
<script src="{{ url_for('static', filename='three.min.js') }}"></script>
<script src="{{ url_for('static', filename='background.js') }}"></script>
```
2. Bearbeiten Sie die Datei `website/templates/mindmap.html` und entfernen Sie die Zeile:
```html
<script src="{{ url_for('static', filename='network-animation.js') }}"></script>
```
3. Entfernen Sie den CSS-Code für `#mindmap-container::before` und die anderen netzwerkspezifischen Stile aus der Datei `website/templates/mindmap.html`.
4. Starten Sie den Flask-Server neu, um die Änderungen zu übernehmen.

33
copy-network-image.bat Normal file
View File

@@ -0,0 +1,33 @@
@echo off
echo Copying network image to website/static/network-bg.jpg...
if not exist "website\static" (
echo Error: website/static directory does not exist.
echo Make sure you are running this script from the main project directory.
pause
exit /b 1
)
if "%~1"=="" (
echo Usage: copy-network-image.bat [path_to_image]
echo Example: copy-network-image.bat d2efd014-1325-471f-b9a7-90d025eb81d6.png
pause
exit /b 1
)
if not exist "%~1" (
echo Error: The specified image file "%~1" does not exist.
pause
exit /b 1
)
copy /Y "%~1" "website\static\network-bg.jpg" > nul
if %errorlevel% equ 0 (
echo Success! The image has been copied to website/static/network-bg.jpg
echo Please restart the Flask server to see the changes.
) else (
echo Error: Failed to copy the image.
)
pause

Binary file not shown.

Binary file not shown.

View File

@@ -9,6 +9,6 @@ openai==1.3.0
requests==2.31.0
flask-cors==4.0.0
gunicorn==21.2.0
pillow==10.0.1
#pillow==10.0.1
pytest==7.4.0
pytest-flask==1.2.0

View File

@@ -0,0 +1,88 @@
// Network Animation Effect
document.addEventListener('DOMContentLoaded', function() {
// Check if we're on the mindmap page
const mindmapContainer = document.getElementById('mindmap-container');
if (!mindmapContainer) return;
// Add enhanced animations for links and nodes
setTimeout(function() {
// Get all SVG links (connections between nodes)
const links = document.querySelectorAll('.link');
const nodes = document.querySelectorAll('.node');
// Add animation to links
links.forEach(link => {
// Create random animation duration between 15 and 30 seconds
const duration = 15 + Math.random() * 15;
link.style.animation = `dash ${duration}s linear infinite`;
link.style.strokeDasharray = '5, 5';
// Add pulse effect on hover
link.addEventListener('mouseover', function() {
this.classList.add('highlighted');
this.style.animation = 'dash 5s linear infinite';
});
link.addEventListener('mouseout', function() {
this.classList.remove('highlighted');
this.style.animation = `dash ${duration}s linear infinite`;
});
});
// Add effects to nodes
nodes.forEach(node => {
node.addEventListener('mouseover', function() {
this.querySelector('circle').style.filter = 'drop-shadow(0 0 15px rgba(179, 143, 255, 0.8))';
// Highlight connected links
const nodeId = this.getAttribute('data-id') || this.id;
links.forEach(link => {
const source = link.getAttribute('data-source');
const target = link.getAttribute('data-target');
if (source === nodeId || target === nodeId) {
link.classList.add('highlighted');
link.style.animation = 'dash 5s linear infinite';
}
});
});
node.addEventListener('mouseout', function() {
this.querySelector('circle').style.filter = 'drop-shadow(0 0 8px rgba(179, 143, 255, 0.5))';
// Remove highlight from connected links
const nodeId = this.getAttribute('data-id') || this.id;
links.forEach(link => {
const source = link.getAttribute('data-source');
const target = link.getAttribute('data-target');
if (source === nodeId || target === nodeId) {
link.classList.remove('highlighted');
const duration = 15 + Math.random() * 15;
link.style.animation = `dash ${duration}s linear infinite`;
}
});
});
});
}, 1000); // Wait for the mindmap to be fully loaded
// Add network background effect
const networkBackground = document.createElement('div');
networkBackground.className = 'network-background';
networkBackground.style.cssText = `
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image: url('/static/network-bg.jpg');
background-size: cover;
background-position: center;
opacity: 0.15;
z-index: -1;
pointer-events: none;
animation: pulse 10s ease-in-out infinite alternate;
`;
mindmapContainer.appendChild(networkBackground);
});

View File

@@ -0,0 +1,118 @@
// Animated Network Background
let canvas, ctx, networkImage;
let isImageLoaded = false;
let animationSpeed = 0.0005; // Speed of rotation
let scaleSpeed = 0.0002; // Speed of scaling
let opacitySpeed = 0.0003; // Speed of opacity change
let rotation = 0;
let scale = 1;
let opacity = 0.6;
let scaleDirection = 1;
let opacityDirection = 1;
// Initialize the canvas and load the image
function initNetworkBackground() {
// Create canvas element if it doesn't exist
if (!document.getElementById('network-background')) {
canvas = document.createElement('canvas');
canvas.id = 'network-background';
canvas.style.position = 'fixed';
canvas.style.top = '0';
canvas.style.left = '0';
canvas.style.width = '100%';
canvas.style.height = '100%';
canvas.style.zIndex = '-1';
document.body.appendChild(canvas);
} else {
canvas = document.getElementById('network-background');
}
// Set canvas size to window size
resizeCanvas();
// Get context
ctx = canvas.getContext('2d');
// Load the network image
networkImage = new Image();
networkImage.src = '/static/network-bg.jpg';
networkImage.onload = function() {
isImageLoaded = true;
animate();
};
// Handle window resize
window.addEventListener('resize', resizeCanvas);
}
// Resize canvas to match window size
function resizeCanvas() {
if (canvas) {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
}
}
// Animation loop
function animate() {
if (!isImageLoaded) return;
// Clear canvas
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Update animation parameters
rotation += animationSpeed;
// Update scale with oscillation
scale += scaleSpeed * scaleDirection;
if (scale > 1.1) {
scaleDirection = -1;
} else if (scale < 0.9) {
scaleDirection = 1;
}
// Update opacity with oscillation
opacity += opacitySpeed * opacityDirection;
if (opacity > 0.8) {
opacityDirection = -1;
} else if (opacity < 0.5) {
opacityDirection = 1;
}
// Save context state
ctx.save();
// Move to center of canvas
ctx.translate(canvas.width / 2, canvas.height / 2);
// Rotate
ctx.rotate(rotation);
// Scale
ctx.scale(scale, scale);
// Set global opacity
ctx.globalAlpha = opacity;
// Draw image centered
ctx.drawImage(
networkImage,
-networkImage.width / 2,
-networkImage.height / 2,
networkImage.width,
networkImage.height
);
// Restore context state
ctx.restore();
// Request next frame
requestAnimationFrame(animate);
}
// Initialize background when the DOM is loaded
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initNetworkBackground);
} else {
initNetworkBackground();
}

View File

@@ -0,0 +1,2 @@
/* This is a placeholder for the network background image.
The actual image (d2efd014-1325-471f-b9a7-90d025eb81d6.png) should be copied here. */

View File

@@ -34,6 +34,9 @@
<!-- Alpine.js -->
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.12.3/dist/cdn.min.js"></script>
<!-- Network Background Script -->
<script src="{{ url_for('static', filename='network-background.js') }}"></script>
<!-- Hauptmodul laden (als ES6 Modul) -->
<script type="module">
import MindMap from "{{ url_for('static', filename='js/main.js') }}";
@@ -515,23 +518,23 @@
<a href="{{ url_for('index') }}"
style="display: flex; align-items: center; padding: 0.5rem 1rem; border-radius: 0.75rem; font-weight: 500; transition: all 0.25s ease; backdrop-filter: blur(15px); -webkit-backdrop-filter: blur(15px);"
x-bind:style="darkMode
? '{{ request.endpoint == 'index' ? 'background: rgba(179, 143, 255, 0.3); color: white; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);' : 'background: transparent; color: rgba(255, 255, 255, 0.9);' }}'
: '{{ request.endpoint == 'index' ? 'background: rgba(179, 143, 255, 0.2); color: rgba(26, 32, 44, 1); box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);' : 'background: transparent; color: rgba(26, 32, 44, 0.9);' }}'">
? '{{ 'background: rgba(179, 143, 255, 0.3); color: white; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);' if request.endpoint == 'index' else 'background: transparent; color: rgba(255, 255, 255, 0.9);' }}'
: '{{ 'background: rgba(179, 143, 255, 0.2); color: rgba(26, 32, 44, 1); box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);' if request.endpoint == 'index' else 'background: transparent; color: rgba(26, 32, 44, 0.9);' }}'">
<i class="fa-solid fa-home" style="margin-right: 0.5rem;"></i>Start
</a>
<a href="{{ url_for('mindmap') }}"
style="display: flex; align-items: center; padding: 0.5rem 1rem; border-radius: 0.75rem; font-weight: 500; transition: all 0.25s ease; backdrop-filter: blur(15px); -webkit-backdrop-filter: blur(15px);"
x-bind:style="darkMode
? '{{ request.endpoint == 'mindmap' ? 'background: rgba(179, 143, 255, 0.3); color: white; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);' : 'background: transparent; color: rgba(255, 255, 255, 0.9);' }}'
: '{{ request.endpoint == 'mindmap' ? 'background: rgba(179, 143, 255, 0.2); color: rgba(26, 32, 44, 1); box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);' : 'background: transparent; color: rgba(26, 32, 44, 0.9);' }}'">
? '{{ 'background: rgba(179, 143, 255, 0.3); color: white; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);' if request.endpoint == 'mindmap' else 'background: transparent; color: rgba(255, 255, 255, 0.9);' }}'
: '{{ 'background: rgba(179, 143, 255, 0.2); color: rgba(26, 32, 44, 1); box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);' if request.endpoint == 'mindmap' else 'background: transparent; color: rgba(26, 32, 44, 0.9);' }}'">
<i class="fa-solid fa-diagram-project" style="margin-right: 0.5rem;"></i>Mindmap
</a>
{% if current_user.is_authenticated %}
<a href="{{ url_for('profile') }}"
style="display: flex; align-items: center; padding: 0.5rem 1rem; border-radius: 0.75rem; font-weight: 500; transition: all 0.25s ease; backdrop-filter: blur(15px); -webkit-backdrop-filter: blur(15px);"
x-bind:style="darkMode
? '{{ request.endpoint == 'profile' ? 'background: rgba(179, 143, 255, 0.3); color: white; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);' : 'background: transparent; color: rgba(255, 255, 255, 0.9);' }}'
: '{{ request.endpoint == 'profile' ? 'background: rgba(179, 143, 255, 0.2); color: rgba(26, 32, 44, 1); box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);' : 'background: transparent; color: rgba(26, 32, 44, 0.9);' }}'">
? '{{ 'background: rgba(179, 143, 255, 0.3); color: white; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);' if request.endpoint == 'profile' else 'background: transparent; color: rgba(255, 255, 255, 0.9);' }}'
: '{{ 'background: rgba(179, 143, 255, 0.2); color: rgba(26, 32, 44, 1); box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);' if request.endpoint == 'profile' else 'background: transparent; color: rgba(26, 32, 44, 0.9);' }}'">
<i class="fa-solid fa-user" style="margin-right: 0.5rem;"></i>Profil
</a>
{% endif %}
@@ -647,23 +650,23 @@
<a href="{{ url_for('index') }}"
style="display: flex; align-items: center; padding: 0.75rem 1rem; margin-bottom: 0.5rem; border-radius: 0.75rem; font-weight: 500; text-decoration: none; transition: all 0.25s ease;"
x-bind:style="darkMode
? '{{ request.endpoint == 'index' ? 'background: rgba(179, 143, 255, 0.3); color: white;' : 'background: transparent; color: rgba(255, 255, 255, 0.9);' }}'
: '{{ request.endpoint == 'index' ? 'background: rgba(179, 143, 255, 0.2); color: rgba(26, 32, 44, 1);' : 'background: transparent; color: rgba(26, 32, 44, 0.9);' }}'">
? '{{ 'background: rgba(179, 143, 255, 0.3); color: white;' if request.endpoint == 'index' else 'background: transparent; color: rgba(255, 255, 255, 0.9);' }}'
: '{{ 'background: rgba(179, 143, 255, 0.2); color: rgba(26, 32, 44, 1);' if request.endpoint == 'index' else 'background: transparent; color: rgba(26, 32, 44, 0.9);' }}'">
<i class="fa-solid fa-home" style="margin-right: 0.5rem; width: 1.25rem;"></i>Start
</a>
<a href="{{ url_for('mindmap') }}"
style="display: flex; align-items: center; padding: 0.75rem 1rem; margin-bottom: 0.5rem; border-radius: 0.75rem; font-weight: 500; text-decoration: none; transition: all 0.25s ease;"
x-bind:style="darkMode
? '{{ request.endpoint == 'mindmap' ? 'background: rgba(179, 143, 255, 0.3); color: white;' : 'background: transparent; color: rgba(255, 255, 255, 0.9);' }}'
: '{{ request.endpoint == 'mindmap' ? 'background: rgba(179, 143, 255, 0.2); color: rgba(26, 32, 44, 1);' : 'background: transparent; color: rgba(26, 32, 44, 0.9);' }}'">
? '{{ 'background: rgba(179, 143, 255, 0.3); color: white;' if request.endpoint == 'mindmap' else 'background: transparent; color: rgba(255, 255, 255, 0.9);' }}'
: '{{ 'background: rgba(179, 143, 255, 0.2); color: rgba(26, 32, 44, 1);' if request.endpoint == 'mindmap' else 'background: transparent; color: rgba(26, 32, 44, 0.9);' }}'">
<i class="fa-solid fa-diagram-project" style="margin-right: 0.5rem; width: 1.25rem;"></i>Mindmap
</a>
{% if current_user.is_authenticated %}
<a href="{{ url_for('profile') }}"
style="display: flex; align-items: center; padding: 0.75rem 1rem; margin-bottom: 0.5rem; border-radius: 0.75rem; font-weight: 500; text-decoration: none; transition: all 0.25s ease;"
x-bind:style="darkMode
? '{{ request.endpoint == 'profile' ? 'background: rgba(179, 143, 255, 0.3); color: white;' : 'background: transparent; color: rgba(255, 255, 255, 0.9);' }}'
: '{{ request.endpoint == 'profile' ? 'background: rgba(179, 143, 255, 0.2); color: rgba(26, 32, 44, 1);' : 'background: transparent; color: rgba(26, 32, 44, 0.9);' }}'">
? '{{ 'background: rgba(179, 143, 255, 0.3); color: white;' if request.endpoint == 'profile' else 'background: transparent; color: rgba(255, 255, 255, 0.9);' }}'
: '{{ 'background: rgba(179, 143, 255, 0.2); color: rgba(26, 32, 44, 1);' if request.endpoint == 'profile' else 'background: transparent; color: rgba(26, 32, 44, 0.9);' }}'">
<i class="fa-solid fa-user" style="margin-right: 0.5rem; width: 1.25rem;"></i>Profil
</a>
{% endif %}

View File

@@ -22,6 +22,52 @@
width: 100%;
}
/* Neuronales Netz / Universum Hintergrund */
.neural-universe-bg {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: radial-gradient(ellipse at center, rgba(30, 20, 60, 0.7) 0%, rgba(10, 10, 25, 0.9) 100%);
z-index: -1;
overflow: hidden;
}
.neural-universe-bg::before {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image:
radial-gradient(circle at 20% 30%, rgba(179, 143, 255, 0.15) 0%, transparent 25%),
radial-gradient(circle at 80% 20%, rgba(88, 169, 255, 0.1) 0%, transparent 20%),
radial-gradient(circle at 40% 80%, rgba(20, 184, 166, 0.12) 0%, transparent 30%),
radial-gradient(circle at 70% 65%, rgba(139, 92, 246, 0.08) 0%, transparent 25%);
z-index: -1;
}
.neural-universe-bg::after {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100"><circle cx="50" cy="50" r="0.5" fill="rgba(255,255,255,0.3)"/></svg>');
background-size: 200px 200px;
opacity: 0.4;
z-index: -1;
animation: twinkling 8s infinite linear;
}
@keyframes twinkling {
from { transform: rotate(0deg) scale(1); }
to { transform: rotate(360deg) scale(1.2); }
}
/* Verbesserte Glasmorphismus-Stile für Karten */
.glass-card, .mindmap-card {
background: rgba(24, 28, 45, 0.75);
@@ -91,6 +137,44 @@
letter-spacing: 0.3px;
}
/* Visuelle Trennung für den unteren Bereich */
.visual-divider {
position: relative;
height: 6px;
width: 100%;
background: linear-gradient(90deg,
transparent 0%,
rgba(179, 143, 255, 0.8) 20%,
rgba(88, 169, 255, 0.8) 50%,
rgba(179, 143, 255, 0.8) 80%,
transparent 100%);
margin: 2rem 0;
box-shadow: 0 0 15px rgba(179, 143, 255, 0.5);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
}
.visual-divider::before, .visual-divider::after {
content: "";
position: absolute;
height: 1px;
width: 100%;
background: linear-gradient(90deg,
transparent 0%,
rgba(255, 255, 255, 0.3) 20%,
rgba(255, 255, 255, 0.5) 50%,
rgba(255, 255, 255, 0.3) 80%,
transparent 100%);
}
.visual-divider::before {
top: -10px;
}
.visual-divider::after {
bottom: -10px;
}
/* Mindmap-Header */
.mindmap-header {
background: rgba(20, 24, 42, 0.85);
@@ -401,113 +485,167 @@
html.light .mindmap-card-footer {
border-color: rgba(0, 0, 0, 0.06);
}
/* Animation für die Verbindungen im Mindmap */
.link {
stroke-dasharray: 5;
animation: dash 30s linear infinite;
stroke-width: 2.5px;
}
@keyframes dash {
to {
stroke-dashoffset: 1000;
}
}
/* Move the selection panel more to the left */
.thoughts-panel {
left: 20px !important; /* Changed from right: 20px */
width: 350px !important; /* Increased from 300px for better visibility */
background: rgba(24, 28, 45, 0.85) !important; /* More visible background */
border: 1px solid rgba(179, 143, 255, 0.3) !important; /* Accent colored border */
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5) !important; /* Stronger shadow */
}
/* Mindmap container with network background */
#mindmap-container::before {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image: url('/static/network-bg.jpg');
background-size: cover;
background-position: center;
opacity: 0.2;
z-index: -1;
animation: pulse 10s ease-in-out infinite alternate;
pointer-events: none;
}
@keyframes pulse {
0% { opacity: 0.1; transform: scale(1); }
100% { opacity: 0.3; transform: scale(1.05); }
}
/* Enhance node visibility */
.node circle {
stroke-width: 3px !important;
filter: drop-shadow(0 0 8px rgba(179, 143, 255, 0.5)) !important;
}
.node.selected circle {
stroke: rgba(179, 143, 255, 0.9) !important;
stroke-width: 4px !important;
filter: drop-shadow(0 0 15px rgba(179, 143, 255, 0.8)) !important;
}
/* Improve visibility of node labels */
.node-label {
font-weight: 700 !important;
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.9) !important;
filter: drop-shadow(0 0 3px rgba(0, 0, 0, 0.8)) !important;
}
/* Make connections more visible */
.link {
stroke: rgba(179, 143, 255, 0.6) !important;
stroke-width: 2.5px !important;
filter: drop-shadow(0 0 5px rgba(179, 143, 255, 0.4)) !important;
}
.link.highlighted {
stroke: rgba(88, 169, 255, 0.8) !important;
stroke-width: 4px !important;
filter: drop-shadow(0 0 8px rgba(88, 169, 255, 0.6)) !important;
}
</style>
{% endblock %}
{% block content %}
<div class="container mx-auto px-4 py-12">
<!-- Feature-Karten-Container -->
<div class="grid grid-cols-1 md:grid-cols-3 gap-8 mb-12">
<!-- Feature-Karte 1: Visualisiere Wissen -->
<div class="feature-card">
<div class="feature-card-icon">
<i class="fas fa-brain"></i>
</div>
<h3>Visualisiere Wissen</h3>
<p>Sieh Wissen als vernetztes System, entdecke Zusammenhänge und erkenne überraschende Verbindungen zwischen verschiedenen Themengebieten.</p>
<div class="relative overflow-hidden">
<!-- Neuronales Netz / Universum Hintergrund -->
<div class="neural-universe-bg"></div>
<div class="container mx-auto px-4 py-8">
<!-- Mindmap-Visualisierung Header -->
<div class="mindmap-header p-6 mb-6">
<h2 class="text-3xl font-bold gradient-text">Wissenslandschaft erkunden</h2>
<p class="text-gray-300 mb-0">Interagiere mit der Mindmap, um Verbindungen zu entdecken und neue Ideen hinzuzufügen</p>
</div>
<!-- Feature-Karte 2: Teile Gedanken -->
<div class="feature-card">
<div class="feature-card-icon">
<i class="fas fa-lightbulb"></i>
</div>
<h3>Teile Gedanken</h3>
<p>Füge deine eigenen Ideen und Perspektiven hinzu. Erstelle Verbindungen zu vorhandenen Gedanken und bereichere die wachsende Wissensbasis.</p>
</div>
<!-- Feature-Karte 3: Community -->
<div class="feature-card">
<div class="feature-card-icon">
<i class="fas fa-users"></i>
</div>
<h3>Community</h3>
<p>Sei Teil einer Gemeinschaft, die gemeinsam ein verteiltes Wissensarchiv aufbaut und sich in thematisch fokussierten Bereichen austauscht.</p>
</div>
</div>
<!-- Mindmap-Visualisierung Header -->
<div class="mindmap-header p-6 mb-6">
<h2 class="text-3xl font-bold mb-2 gradient-text">Wissenslandschaft erkunden</h2>
<p class="text-gray-300 mb-0">Interagiere mit der Mindmap, um Verbindungen zu entdecken und neue Ideen hinzuzufügen</p>
</div>
<!-- Mindmap-Container -->
<div class="glass-card overflow-hidden mb-12">
<div id="mindmap-container" class="relative" style="height: 70vh; min-height: 500px;">
<!-- Lade-Overlay -->
<div class="mindmap-loading absolute inset-0 flex items-center justify-center z-10" style="background: rgba(14, 18, 32, 0.7); backdrop-filter: blur(5px);">
<div class="text-center">
<div class="inline-block animate-spin rounded-full h-12 w-12 border-t-2 border-b-2 border-purple-500 mb-4"></div>
<p class="text-white text-lg">Wissenslandschaft wird geladen...</p>
<div class="w-64 h-2 bg-gray-700 rounded-full mt-4 overflow-hidden">
<div class="loading-progress h-full bg-gradient-to-r from-purple-500 to-blue-500 rounded-full" style="width: 0%"></div>
<!-- Mindmap-Container - Jetzt größer -->
<div class="glass-card overflow-hidden mb-12">
<div id="mindmap-container" class="relative" style="height: 80vh; min-height: 700px;">
<!-- Lade-Overlay -->
<div class="mindmap-loading absolute inset-0 flex items-center justify-center z-10" style="background: rgba(14, 18, 32, 0.7); backdrop-filter: blur(5px);">
<div class="text-center">
<div class="inline-block animate-spin rounded-full h-12 w-12 border-t-2 border-b-2 border-purple-500 mb-4"></div>
<p class="text-white text-lg">Wissenslandschaft wird geladen...</p>
<div class="w-64 h-2 bg-gray-700 rounded-full mt-4 overflow-hidden">
<div class="loading-progress h-full bg-gradient-to-r from-purple-500 to-blue-500 rounded-full" style="width: 0%"></div>
</div>
</div>
</div>
</div>
<!-- Steuerungsleiste -->
<div class="controls-bar p-4 flex flex-wrap items-center justify-between gap-3">
<div class="flex flex-wrap gap-2">
<button class="control-btn" id="zoom-in-btn">
<i class="fas fa-search-plus mr-1"></i> Vergrößern
</button>
<button class="control-btn" id="zoom-out-btn">
<i class="fas fa-search-minus mr-1"></i> Verkleinern
</button>
<button class="control-btn" id="center-btn">
<i class="fas fa-bullseye mr-1"></i> Zentrieren
</button>
</div>
<div class="flex flex-wrap gap-2">
<button class="control-btn" id="add-thought-btn">
<i class="fas fa-plus-circle mr-1"></i> Gedanke hinzufügen
</button>
<button class="control-btn" id="connect-btn">
<i class="fas fa-link mr-1"></i> Verbinden
</button>
</div>
</div>
</div>
<!-- Steuerungsleiste -->
<div class="controls-bar p-4 flex flex-wrap items-center justify-between gap-3">
<div class="flex flex-wrap gap-2">
<button class="control-btn" id="zoom-in-btn">
<i class="fas fa-search-plus mr-1"></i> Vergrößern
</button>
<button class="control-btn" id="zoom-out-btn">
<i class="fas fa-search-minus mr-1"></i> Verkleinern
</button>
<button class="control-btn" id="center-btn">
<i class="fas fa-bullseye mr-1"></i> Zentrieren
</button>
</div>
<div class="flex flex-wrap gap-2">
<button class="control-btn" id="add-thought-btn">
<i class="fas fa-plus-circle mr-1"></i> Gedanke hinzufügen
</button>
<button class="control-btn" id="connect-btn">
<i class="fas fa-link mr-1"></i> Verbinden
</button>
</div>
</div>
</div>
<!-- Visuelle Trennung -->
<div class="visual-divider"></div>
<!-- Unterer Bereich: KI-Assistenz, Suche und Lernpfade -->
<div class="grid grid-cols-1 md:grid-cols-3 gap-8">
<!-- KI-Assistenz -->
<div class="feature-card">
<div class="feature-card-icon">
<i class="fas fa-robot"></i>
<!-- Unterer Bereich: KI-Assistenz, Suche und Lernpfade -->
<div class="grid grid-cols-1 md:grid-cols-3 gap-8">
<!-- KI-Assistenz -->
<div class="feature-card">
<div class="feature-card-icon">
<i class="fas fa-robot"></i>
</div>
<h3>KI-Assistenz</h3>
<p>Lass dir von künstlicher Intelligenz helfen, neue Zusammenhänge zu entdecken, Inhalte zusammenzufassen und Fragen zu beantworten.</p>
</div>
<h3>KI-Assistenz</h3>
<p>Lass dir von künstlicher Intelligenz helfen, neue Zusammenhänge zu entdecken, Inhalte zusammenzufassen und Fragen zu beantworten.</p>
</div>
<!-- Intelligente Suche -->
<div class="feature-card">
<div class="feature-card-icon">
<i class="fas fa-search"></i>
<!-- Intelligente Suche -->
<div class="feature-card">
<div class="feature-card-icon">
<i class="fas fa-search"></i>
</div>
<h3>Intelligente Suche</h3>
<p>Finde genau die Informationen, die du suchst, mit fortschrittlichen Such- und Filterfunktionen für eine präzise Navigation durch das Wissen.</p>
</div>
<h3>Intelligente Suche</h3>
<p>Finde genau die Informationen, die du suchst, mit fortschrittlichen Such- und Filterfunktionen für eine präzise Navigation durch das Wissen.</p>
</div>
<!-- Geführte Pfade -->
<div class="feature-card">
<div class="feature-card-icon">
<i class="fas fa-map-signs"></i>
<!-- Geführte Pfade -->
<div class="feature-card">
<div class="feature-card-icon">
<i class="fas fa-map-signs"></i>
</div>
<h3>Geführte Pfade</h3>
<p>Folge kuratierten Lernpfaden durch komplexe Themen oder erschaffe selbst Routen für andere, die deinen Gedankengängen folgen möchten.</p>
</div>
<h3>Geführte Pfade</h3>
<p>Folge kuratierten Lernpfaden durch komplexe Themen oder erschaffe selbst Routen für andere, die deinen Gedankengängen folgen möchten.</p>
</div>
</div>
</div>
@@ -523,9 +661,73 @@
<script src="{{ url_for('static', filename='d3-extensions.js') }}"></script>
<!-- Mindmap JS -->
<script src="{{ url_for('static', filename='mindmap.js') }}"></script>
<script src="{{ url_for('static', filename='network-animation.js') }}"></script>
<script>
// Dynamische Neuronen-Netz-Animation im Hintergrund
document.addEventListener('DOMContentLoaded', function() {
// Animation des neuronalen Netzwerks hinzufügen
const neuralBg = document.querySelector('.neural-universe-bg');
// Neuronenpunkte erstellen
const neuronCount = 100;
for (let i = 0; i < neuronCount; i++) {
const neuron = document.createElement('div');
neuron.className = 'neuron-point';
// Zufällige Position
const posX = Math.random() * 100;
const posY = Math.random() * 100;
const size = Math.random() * 3 + 1;
const animDuration = Math.random() * 50 + 20;
// Styling mit Glasmorphismus
neuron.style.cssText = `
position: absolute;
left: ${posX}%;
top: ${posY}%;
width: ${size}px;
height: ${size}px;
background: rgba(255, 255, 255, ${Math.random() * 0.3 + 0.1});
border-radius: 50%;
filter: blur(${Math.random() * 1}px);
box-shadow: 0 0 ${Math.random() * 10 + 5}px rgba(179, 143, 255, 0.5);
animation: pulse ${animDuration}s infinite alternate ease-in-out;
`;
neuralBg.appendChild(neuron);
}
// Verbindungen zwischen Neuronen erstellen
const connectionCount = 40;
for (let i = 0; i < connectionCount; i++) {
const connection = document.createElement('div');
connection.className = 'neuron-connection';
// Zufällige Position und Rotation für Verbindungen
const posX = Math.random() * 100;
const posY = Math.random() * 100;
const width = Math.random() * 150 + 50;
const height = Math.random() * 1 + 0.5;
const rotation = Math.random() * 360;
const opacity = Math.random() * 0.2 + 0.05;
const animDuration = Math.random() * 20 + 10;
connection.style.cssText = `
position: absolute;
left: ${posX}%;
top: ${posY}%;
width: ${width}px;
height: ${height}px;
background: linear-gradient(90deg, transparent, rgba(179, 143, 255, ${opacity}), transparent);
transform: rotate(${rotation}deg);
animation: flash ${animDuration}s infinite alternate ease-in-out;
opacity: ${opacity};
`;
neuralBg.appendChild(connection);
}
// Initialisiere die Mindmap-Visualisierung
const mindmapContainer = document.getElementById('mindmap-container');
const containerWidth = mindmapContainer.clientWidth;
@@ -658,5 +860,21 @@
}
});
});
// Animationen für die Hintergrundeffekte
document.head.insertAdjacentHTML('beforeend', `
<style>
@keyframes pulse {
0% { transform: scale(1); opacity: 0.5; }
100% { transform: scale(1.5); opacity: 0.2; }
}
@keyframes flash {
0% { opacity: 0.02; }
50% { opacity: 0.2; }
100% { opacity: 0.08; }
}
</style>
`);
</script>
{% endblock %}