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:
69
ANLEITUNG.md
Normal file
69
ANLEITUNG.md
Normal 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
33
copy-network-image.bat
Normal 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
|
||||
BIN
website/__pycache__/app.cpython-313.pyc
Normal file
BIN
website/__pycache__/app.cpython-313.pyc
Normal file
Binary file not shown.
BIN
website/__pycache__/init_db.cpython-313.pyc
Normal file
BIN
website/__pycache__/init_db.cpython-313.pyc
Normal file
Binary file not shown.
@@ -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
|
||||
88
website/static/network-animation.js
Normal file
88
website/static/network-animation.js
Normal 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);
|
||||
});
|
||||
118
website/static/network-background.js
Normal file
118
website/static/network-background.js
Normal 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();
|
||||
}
|
||||
2
website/static/network-bg.jpg
Normal file
2
website/static/network-bg.jpg
Normal 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. */
|
||||
@@ -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 %}
|
||||
|
||||
@@ -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 %}
|
||||
Reference in New Issue
Block a user