Aktualisiere die Konfiguration der neuronalen Netzwerk-Hintergrundanimation in neural-network-background.js, um die Anzahl der Knoten, Variationen, Geschwindigkeiten und Sichtbarkeiten anzupassen. Füge neue Parameter für aktive Flows und Flussweiterleitung hinzu, um die Animation dynamischer zu gestalten. Optimiere die Logik zur Verwaltung aktiver Flows und verbessere die Sichtbarkeit von Verbindungen für ein flüssigeres Benutzererlebnis.

This commit is contained in:
2025-04-29 15:19:33 +02:00
parent d7e6912e08
commit d307763007

View File

@@ -71,26 +71,29 @@ class NeuralNetworkBackground {
// Konfigurationsobjekt für schlangenartige, leuchtende Blitze und permanentes Netzwerk // Konfigurationsobjekt für schlangenartige, leuchtende Blitze und permanentes Netzwerk
this.config = { this.config = {
nodeCount: 140, // Weniger Knoten für klarere Strukturen nodeCount: 180, // Weniger Knoten für klarere Strukturen
nodeSize: 3.2, // Etwas größere Knoten für bessere Sichtbarkeit nodeSize: 3.2, // Etwas größere Knoten für bessere Sichtbarkeit
nodeVariation: 0.5, // Reduzierte Varianz für konsistenteres Erscheinungsbild nodeVariation: 12, // Reduzierte Varianz für konsistenteres Erscheinungsbild
connectionDistance: 320, // Größere Verbindungsdistanz für weitläufigeres Netzwerk connectionDistance: 320, // Größere Verbindungsdistanz für weitläufigeres Netzwerk
connectionOpacity: 0.3, // Erhöhte Opazität für sichtbarere dauerhafte Verbindungen connectionOpacity: 0.3, // Erhöhte Opazität für sichtbarere dauerhafte Verbindungen
animationSpeed: 0.018, // Noch langsamere Animation für sanftere Bewegung animationSpeed: 0.1, // Noch langsamere Animation für sanftere Bewegung
pulseSpeed: 0.007, // Sehr langsames Pulsieren für ruhigere Animation pulseSpeed: 0.1, // Sehr langsames Pulsieren für ruhige Animation
flowSpeed: 0.45, // Deutlich langsamere Blitze für schlangenartige Bewegung flowSpeed: 0.15, // Deutlich langsamere Blitze für schlangenartige Bewegung
flowDensity: 15, // Mehr gleichzeitige Blitze flowDensity: 2, // Weniger gleichzeitige Blitze für bessere Verteilung
flowLength: 0.20, // Deutlich kürzere einzelne Flows für sichtbare "Schlangen-Segmente" flowLength: 0.05, // Längere einzelne Flows für sichtbare "Schlangen"
maxConnections: 22, // Mehr Verbindungen pro Neuron für dichtere Netzwerke maxConnections: 22, // Mehr Verbindungen pro Neuron für dichtere Netzwerke
clusteringFactor: 0.6, // Stärkeres Clustering für deutlichere Strukturen clusteringFactor: 0.005, // Stärkeres Clustering für deutlichere Strukturen
linesFadeDuration: 60000, // Noch längere Dauer fürs Ein-/Ausblenden für permanentes Netzwerk (ms) linesFadeDuration: 60000, // Noch längere Dauer fürs Ein-/Ausblenden für permanentes Netzwerk (ms)
linesWidth: 1.8, // Etwas dickere Linien für bessere Sichtbarkeit linesWidth: 1.0, // Etwas dickere Linien für bessere Sichtbarkeit
linesOpacity: 0.75, // Höhere Opazität für das permanente Netzwerk linesOpacity: 0.75, // Höhere Opazität für das permanente Netzwerk
maxFlowCount: 110, // Mehr gleichzeitige Flows für lebendige Aktivität maxFlowCount: 8, // Weniger gleichzeitige Flows für bessere Übersicht
glowIntensity: 2.5, // Verstärkter Glow-Effekt (neu) glowIntensity: 2.5, // Verstärkter Glow-Effekt
sparkCount: 8, // Mehr Funken (neu) sparkCount: 2, // Mehr Funken
sparkSize: 3.5, // Größere Funken (neu) sparkSize: 2.5, // Größere Funken
blurRadius: 12 // Blur-Radius für Glow-Effekte (neu) blurRadius: 20, // Blur-Radius für Glow-Effekte
minActiveFlows: 30, // Minimale Anzahl aktiver Flows
flowForwardingRate: 1.0, // 100% Weiterleitungsrate für endlose Flows
maxFlowGenerations: 100 // Sehr hohe Generationsgrenze für endlose Animation
}; };
// Initialize // Initialize
@@ -633,6 +636,14 @@ class NeuralNetworkBackground {
// Track new flows to add after the loop to avoid modifying the array during iteration // Track new flows to add after the loop to avoid modifying the array during iteration
const newFlows = []; const newFlows = [];
// Zähle aktive Flows
const activeFlows = this.flows.length;
// Wenn zu wenige Flows aktiv sind, starte neue Major Flow Cascades
if (activeFlows < this.config.minActiveFlows) {
this.initiateMajorFlowCascade(now);
}
// Update existing flows // Update existing flows
for (let i = this.flows.length - 1; i >= 0; i--) { for (let i = this.flows.length - 1; i >= 0; i--) {
const flow = this.flows[i]; const flow = this.flows[i];
@@ -654,7 +665,7 @@ class NeuralNetworkBackground {
} }
// Zielknoten aktivieren und Weiterleitung starten, wenn der Flow ihn erreicht hat // Zielknoten aktivieren und Weiterleitung starten, wenn der Flow ihn erreicht hat
if (flow.targetNodeIdx !== undefined && flow.progress > 0.80) { // Noch früher auslösen für kontinuierlicheren Fluss if (flow.targetNodeIdx !== undefined && flow.progress > 0.80) {
const targetNode = this.nodes[flow.targetNodeIdx]; const targetNode = this.nodes[flow.targetNodeIdx];
targetNode.isActive = true; targetNode.isActive = true;
targetNode.lastFired = now; targetNode.lastFired = now;
@@ -664,22 +675,19 @@ class NeuralNetworkBackground {
if (flow.connection.fadeState !== 'visible') { if (flow.connection.fadeState !== 'visible') {
flow.connection.fadeState = 'visible'; flow.connection.fadeState = 'visible';
flow.connection.fadeStartTime = now; flow.connection.fadeStartTime = now;
// Permanente Sichtbarkeit für Verbindungen
flow.connection.visibleDuration = 600000 + Math.random() * 300000; // 10-15 Minuten sichtbar flow.connection.visibleDuration = 600000 + Math.random() * 300000; // 10-15 Minuten sichtbar
} }
// Flow ist am Ziel angekommen, starte Weiterleitung zu anderen Knoten // Flow ist am Ziel angekommen, starte Weiterleitung zu anderen Knoten
// Jeder Flow leitet genau einmal weiter, unabhängig von der Generation // Jeder Flow leitet genau einmal weiter
if (!flow.hasForwarded && targetNode.connections.length > 0) { if (!flow.hasForwarded && targetNode.connections.length > 0) {
// Markiere, dass dieser Flow bereits weitergeleitet wurde
flow.hasForwarded = true; flow.hasForwarded = true;
// Durch reduzierte Anzahl der Weiterleitungen schaffen wir einen endloseren Eindruck // Durch reduzierte Anzahl der Weiterleitungen schaffen wir einen endloseren Eindruck
// mit sichtbaren "Schlangen", die durch das Netzwerk ziehen
const connCount = Math.min(3, targetNode.connections.length); const connCount = Math.min(3, targetNode.connections.length);
const availableConnections = [...targetNode.connections]; const availableConnections = [...targetNode.connections];
// Keine Weiterleitung an die Quelle des Flows zurück, es sei denn, es ist die einzige Option // Keine Weiterleitung an die Quelle des Flows zurück
if (flow.sourceNodeIdx !== undefined && availableConnections.length > 1) { if (flow.sourceNodeIdx !== undefined && availableConnections.length > 1) {
const sourceIndex = availableConnections.indexOf(flow.sourceNodeIdx); const sourceIndex = availableConnections.indexOf(flow.sourceNodeIdx);
if (sourceIndex >= 0) { if (sourceIndex >= 0) {
@@ -691,13 +699,11 @@ class NeuralNetworkBackground {
if (availableConnections.length > 0) { if (availableConnections.length > 0) {
// Priorisiere ungenutzte Pfade für ein dynamischeres Netzwerk // Priorisiere ungenutzte Pfade für ein dynamischeres Netzwerk
const sortedConnections = availableConnections.map(nodeIdx => { const sortedConnections = availableConnections.map(nodeIdx => {
// Finde die Verbindung zwischen diesem und dem Zielknoten
const conn = this.connections.find(c => const conn = this.connections.find(c =>
(c.from === flow.targetNodeIdx && c.to === nodeIdx) || (c.from === flow.targetNodeIdx && c.to === nodeIdx) ||
(c.from === nodeIdx && c.to === flow.targetNodeIdx) (c.from === nodeIdx && c.to === flow.targetNodeIdx)
); );
// Bewerte Verbindungen - bevorzuge solche, die länger nicht aktiviert wurden
const timeSinceLastActivation = conn ? now - (conn.lastActivated || 0) : 0; const timeSinceLastActivation = conn ? now - (conn.lastActivated || 0) : 0;
const connectionCount = this.nodes[nodeIdx].connections.length; const connectionCount = this.nodes[nodeIdx].connections.length;
@@ -705,86 +711,66 @@ class NeuralNetworkBackground {
nodeIdx, nodeIdx,
connectionCount, connectionCount,
timeSinceLastActivation, timeSinceLastActivation,
// Kombinierter Score für Bewertung score: (timeSinceLastActivation * 0.00001) +
score: (timeSinceLastActivation * 0.00001) + // Bevorzuge länger inaktive Verbindungen (connectionCount * 0.2) +
(connectionCount * 0.2) + // Bevorzuge gut vernetzte Knoten (Math.random() * 0.5)
(Math.random() * 0.5) // Zufallskomponente für Variation
}; };
}).sort((a, b) => b.score - a.score); }).sort((a, b) => b.score - a.score);
// Wähle priorisierte Verbindungen // Wähle priorisierte Verbindungen
for (let j = 0; j < connCount && j < sortedConnections.length; j++) { for (let j = 0; j < connCount && j < sortedConnections.length; j++) {
const nextNodeIdx = sortedConnections[j].nodeIdx; const nextNodeIdx = sortedConnections[j].nodeIdx;
// Finde die Verbindung zwischen dem Target-Knoten und dem nächsten Knoten
const nextConn = this.connections.find(c => const nextConn = this.connections.find(c =>
(c.from === flow.targetNodeIdx && c.to === nextNodeIdx) || (c.from === flow.targetNodeIdx && c.to === nextNodeIdx) ||
(c.from === nextNodeIdx && c.to === flow.targetNodeIdx) (c.from === nextNodeIdx && c.to === flow.targetNodeIdx)
); );
if (nextConn) { if (nextConn) {
// Verbindung aktivieren
nextConn.lastActivated = now; nextConn.lastActivated = now;
// Stelle sicher, dass die Verbindung dauerhaft sichtbar bleibt if (nextConn.fadeState !== 'visible') {
if (nextConn.fadeState === 'out' || nextConn.fadeState === 'hidden') { nextConn.fadeState = 'visible';
nextConn.fadeState = 'visible'; // Setze auf sichtbar zurück
nextConn.fadeStartTime = now;
// Verbindungen bleiben extrem lange sichtbar, um ein permanentes Netzwerk zu bilden
nextConn.visibleDuration = 600000 + Math.random() * 300000; // 10-15 Minuten sichtbar
} else if (nextConn.fadeState === 'visible') {
// Verlängere die Sichtbarkeit
nextConn.fadeStartTime = now; nextConn.fadeStartTime = now;
nextConn.visibleDuration = 600000 + Math.random() * 300000;
} }
// Verbindung schneller aufbauen
if (nextConn.progress < 1) { if (nextConn.progress < 1) {
nextConn.buildSpeed = 0.04 + Math.random() * 0.02; // Noch schnellerer Aufbau nextConn.buildSpeed = 0.04 + Math.random() * 0.02;
} }
// Berechne die nächste Generation - aber begrenze die Tiefe
const nextGeneration = (flow.generation || 1) + 1; const nextGeneration = (flow.generation || 1) + 1;
const maxGeneration = 200; // Extrem hohe Grenze für kontinuierliche Animation
if (nextGeneration <= maxGeneration) { if (nextGeneration <= this.config.maxFlowGenerations) {
// Richtung des Flows bestimmen
const direction = nextConn.from === flow.targetNodeIdx; const direction = nextConn.from === flow.targetNodeIdx;
// Für kontinuierliche Schlangenlinien: Berechne die zeitliche Verzögerung // Berechne Verzögerung basierend auf Verbindungslänge
// basierend auf Generation und Connection-Länge
const connectionLength = Math.sqrt( const connectionLength = Math.sqrt(
Math.pow(this.nodes[nextConn.to].x - this.nodes[nextConn.from].x, 2) + Math.pow(this.nodes[nextConn.to].x - this.nodes[nextConn.from].x, 2) +
Math.pow(this.nodes[nextConn.to].y - this.nodes[nextConn.from].y, 2) Math.pow(this.nodes[nextConn.to].y - this.nodes[nextConn.from].y, 2)
); );
// Adaptiere die Verzögerung basierend auf Verbindungslänge und Generation const baseDelay = 80;
// Kürzere Verbindungen und höhere Generationen haben weniger Verzögerung const lengthFactor = Math.min(1.2, connectionLength / 200);
const baseDelay = 80; // Basis-Verzögerung in ms const genFactor = Math.max(0.2, 1.0 - (nextGeneration * 0.005));
const lengthFactor = Math.min(1.2, connectionLength / 200); // 0.1-1.2 basierend auf Länge
const genFactor = Math.max(0.2, 1.0 - (nextGeneration * 0.005)); // Reduziert mit Generation
const delay = baseDelay * lengthFactor * genFactor; const delay = baseDelay * lengthFactor * genFactor;
// Etwas kürzere Flows für schnellere Propagation durch das Netzwerk
setTimeout(() => { setTimeout(() => {
// Prüfe, ob das Animation noch läuft, bevor ein neuer Flow hinzugefügt wird
if (!this.isDestroying && this.animationFrameId) { if (!this.isDestroying && this.animationFrameId) {
// Für längere "Schlangen": Benutze dasselbe hasForwarded-Flag für alle Flows
// einer Generation, um endlosen Fluss zu ermöglichen
newFlows.push({ newFlows.push({
id: now + '_' + Math.random().toString(36).substr(2, 9),
connection: nextConn, connection: nextConn,
progress: 0, progress: 0,
direction: direction, direction: direction,
length: this.config.flowLength * (0.9 + Math.random() * 0.2), // Leichte Variation der Länge length: this.config.flowLength * (0.9 + Math.random() * 0.2),
creationTime: Date.now(), creationTime: Date.now(),
// Längere Duration für höhere Generationen - schafft sichtbare "Schlangen"
totalDuration: 600 + Math.random() * 300 + (nextGeneration * 5), totalDuration: 600 + Math.random() * 300 + (nextGeneration * 5),
sourceNodeIdx: direction ? nextConn.from : nextConn.to, sourceNodeIdx: direction ? nextConn.from : nextConn.to,
targetNodeIdx: direction ? nextConn.to : nextConn.from, targetNodeIdx: direction ? nextConn.to : nextConn.from,
fadeFactor: flow.fadeFactor || 1.0, fadeFactor: flow.fadeFactor || 1.0,
isForwarded: false, // Zurückgesetzt, damit auch dieser Flow weiterleiten kann isForwarded: false,
generation: nextGeneration, generation: nextGeneration,
hasForwarded: false, // Jeder Flow leitet genau einmal weiter hasForwarded: false,
parentFlow: flow.id // Merke, von welchem Flow dieser stammt parentFlow: flow.id
}); });
} }
}, delay); }, delay);
@@ -798,27 +784,23 @@ class NeuralNetworkBackground {
// Stellen Sie sicher, dass die Verbindung aktiv bleibt // Stellen Sie sicher, dass die Verbindung aktiv bleibt
flow.connection.lastActivated = now; flow.connection.lastActivated = now;
// Erhöhe die Sichtbarkeitsdauer jeder aktivierten Verbindung
if (flow.connection.fadeState === 'visible') { if (flow.connection.fadeState === 'visible') {
// Stelle sicher, dass bereits sichtbare Verbindungen permanent sichtbar bleiben
flow.connection.visibleDuration = Math.max( flow.connection.visibleDuration = Math.max(
flow.connection.visibleDuration || 300000, flow.connection.visibleDuration || 300000,
600000 + Math.random() * 300000 // 10-15 Minuten Mindest-Sichtbarkeit 600000 + Math.random() * 300000
); );
} }
// Remove completed flows, but ensure parent-child relationships for visible "snakes" // Remove completed flows, but ensure parent-child relationships for visible "snakes"
// Bei "schlangenhaften" Flows: Entferne nur, wenn der Flow zu Ende ist UND ein Kind hat
// oder wenn er sein Maximum erreicht hat
const isComplete = flow.progress > 1.0 || flowProgress >= 1.0; const isComplete = flow.progress > 1.0 || flowProgress >= 1.0;
const hasMaxGeneration = flow.generation && flow.generation > 200; const hasMaxGeneration = flow.generation && flow.generation > this.config.maxFlowGenerations;
if (isComplete || hasMaxGeneration) { if (isComplete || hasMaxGeneration) {
this.flows.splice(i, 1); this.flows.splice(i, 1);
} }
} }
// Füge alle neuen Flows hinzu, die während der Iteration erzeugt wurden // Füge alle neuen Flows hinzu
this.flows.push(...newFlows); this.flows.push(...newFlows);
} }
@@ -1971,7 +1953,7 @@ class NeuralNetworkBackground {
); );
// Dynamische Amplitude basierend auf Distanz // Dynamische Amplitude basierend auf Distanz
const baseAmplitude = amplitude * (totalDistance / 100); const baseAmplitude = amplitude * (totalDistance / 150);
// Welle für schlangenartigen Effekt // Welle für schlangenartigen Effekt
const waveFrequency = 2 + Math.random() * 1.5; // Zusätzlicher Welleneffekt const waveFrequency = 2 + Math.random() * 1.5; // Zusätzlicher Welleneffekt