diff --git a/static/neural-network-background.js b/static/neural-network-background.js index 4413ffa..55b881d 100644 --- a/static/neural-network-background.js +++ b/static/neural-network-background.js @@ -71,26 +71,29 @@ class NeuralNetworkBackground { // Konfigurationsobjekt für schlangenartige, leuchtende Blitze und permanentes Netzwerk 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 - 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 connectionOpacity: 0.3, // Erhöhte Opazität für sichtbarere dauerhafte Verbindungen - animationSpeed: 0.018, // Noch langsamere Animation für sanftere Bewegung - pulseSpeed: 0.007, // Sehr langsames Pulsieren für ruhigere Animation - flowSpeed: 0.45, // Deutlich langsamere Blitze für schlangenartige Bewegung - flowDensity: 15, // Mehr gleichzeitige Blitze - flowLength: 0.20, // Deutlich kürzere einzelne Flows für sichtbare "Schlangen-Segmente" + animationSpeed: 0.1, // Noch langsamere Animation für sanftere Bewegung + pulseSpeed: 0.1, // Sehr langsames Pulsieren für ruhige Animation + flowSpeed: 0.15, // Deutlich langsamere Blitze für schlangenartige Bewegung + flowDensity: 2, // Weniger gleichzeitige Blitze für bessere Verteilung + flowLength: 0.05, // Längere einzelne Flows für sichtbare "Schlangen" 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) - 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 - maxFlowCount: 110, // Mehr gleichzeitige Flows für lebendige Aktivität - glowIntensity: 2.5, // Verstärkter Glow-Effekt (neu) - sparkCount: 8, // Mehr Funken (neu) - sparkSize: 3.5, // Größere Funken (neu) - blurRadius: 12 // Blur-Radius für Glow-Effekte (neu) + maxFlowCount: 8, // Weniger gleichzeitige Flows für bessere Übersicht + glowIntensity: 2.5, // Verstärkter Glow-Effekt + sparkCount: 2, // Mehr Funken + sparkSize: 2.5, // Größere Funken + 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 @@ -633,6 +636,14 @@ class NeuralNetworkBackground { // Track new flows to add after the loop to avoid modifying the array during iteration 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 for (let i = this.flows.length - 1; i >= 0; i--) { const flow = this.flows[i]; @@ -654,7 +665,7 @@ class NeuralNetworkBackground { } // 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]; targetNode.isActive = true; targetNode.lastFired = now; @@ -664,22 +675,19 @@ class NeuralNetworkBackground { if (flow.connection.fadeState !== 'visible') { flow.connection.fadeState = 'visible'; flow.connection.fadeStartTime = now; - // Permanente Sichtbarkeit für Verbindungen flow.connection.visibleDuration = 600000 + Math.random() * 300000; // 10-15 Minuten sichtbar } // 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) { - // Markiere, dass dieser Flow bereits weitergeleitet wurde flow.hasForwarded = true; // 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]; - // 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) { const sourceIndex = availableConnections.indexOf(flow.sourceNodeIdx); if (sourceIndex >= 0) { @@ -691,13 +699,11 @@ class NeuralNetworkBackground { if (availableConnections.length > 0) { // Priorisiere ungenutzte Pfade für ein dynamischeres Netzwerk const sortedConnections = availableConnections.map(nodeIdx => { - // Finde die Verbindung zwischen diesem und dem Zielknoten const conn = this.connections.find(c => (c.from === flow.targetNodeIdx && c.to === nodeIdx) || (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 connectionCount = this.nodes[nodeIdx].connections.length; @@ -705,86 +711,66 @@ class NeuralNetworkBackground { nodeIdx, connectionCount, timeSinceLastActivation, - // Kombinierter Score für Bewertung - score: (timeSinceLastActivation * 0.00001) + // Bevorzuge länger inaktive Verbindungen - (connectionCount * 0.2) + // Bevorzuge gut vernetzte Knoten - (Math.random() * 0.5) // Zufallskomponente für Variation + score: (timeSinceLastActivation * 0.00001) + + (connectionCount * 0.2) + + (Math.random() * 0.5) }; }).sort((a, b) => b.score - a.score); // Wähle priorisierte Verbindungen for (let j = 0; j < connCount && j < sortedConnections.length; j++) { const nextNodeIdx = sortedConnections[j].nodeIdx; - - // Finde die Verbindung zwischen dem Target-Knoten und dem nächsten Knoten const nextConn = this.connections.find(c => (c.from === flow.targetNodeIdx && c.to === nextNodeIdx) || (c.from === nextNodeIdx && c.to === flow.targetNodeIdx) ); if (nextConn) { - // Verbindung aktivieren nextConn.lastActivated = now; - // Stelle sicher, dass die Verbindung dauerhaft sichtbar bleibt - if (nextConn.fadeState === 'out' || nextConn.fadeState === 'hidden') { - 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 + if (nextConn.fadeState !== 'visible') { + nextConn.fadeState = 'visible'; nextConn.fadeStartTime = now; + nextConn.visibleDuration = 600000 + Math.random() * 300000; } - // Verbindung schneller aufbauen 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 maxGeneration = 200; // Extrem hohe Grenze für kontinuierliche Animation - if (nextGeneration <= maxGeneration) { - // Richtung des Flows bestimmen + if (nextGeneration <= this.config.maxFlowGenerations) { const direction = nextConn.from === flow.targetNodeIdx; - // Für kontinuierliche Schlangenlinien: Berechne die zeitliche Verzögerung - // basierend auf Generation und Connection-Länge + // Berechne Verzögerung basierend auf Verbindungslänge const connectionLength = Math.sqrt( 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) ); - // Adaptiere die Verzögerung basierend auf Verbindungslänge und Generation - // Kürzere Verbindungen und höhere Generationen haben weniger Verzögerung - const baseDelay = 80; // Basis-Verzögerung in ms - 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 baseDelay = 80; + const lengthFactor = Math.min(1.2, connectionLength / 200); + const genFactor = Math.max(0.2, 1.0 - (nextGeneration * 0.005)); const delay = baseDelay * lengthFactor * genFactor; - // Etwas kürzere Flows für schnellere Propagation durch das Netzwerk setTimeout(() => { - // Prüfe, ob das Animation noch läuft, bevor ein neuer Flow hinzugefügt wird 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({ + id: now + '_' + Math.random().toString(36).substr(2, 9), connection: nextConn, progress: 0, 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(), - // Längere Duration für höhere Generationen - schafft sichtbare "Schlangen" totalDuration: 600 + Math.random() * 300 + (nextGeneration * 5), sourceNodeIdx: direction ? nextConn.from : nextConn.to, targetNodeIdx: direction ? nextConn.to : nextConn.from, fadeFactor: flow.fadeFactor || 1.0, - isForwarded: false, // Zurückgesetzt, damit auch dieser Flow weiterleiten kann + isForwarded: false, generation: nextGeneration, - hasForwarded: false, // Jeder Flow leitet genau einmal weiter - parentFlow: flow.id // Merke, von welchem Flow dieser stammt + hasForwarded: false, + parentFlow: flow.id }); } }, delay); @@ -798,27 +784,23 @@ class NeuralNetworkBackground { // Stellen Sie sicher, dass die Verbindung aktiv bleibt flow.connection.lastActivated = now; - // Erhöhe die Sichtbarkeitsdauer jeder aktivierten Verbindung if (flow.connection.fadeState === 'visible') { - // Stelle sicher, dass bereits sichtbare Verbindungen permanent sichtbar bleiben flow.connection.visibleDuration = Math.max( 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" - // 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 hasMaxGeneration = flow.generation && flow.generation > 200; + const hasMaxGeneration = flow.generation && flow.generation > this.config.maxFlowGenerations; if (isComplete || hasMaxGeneration) { 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); } @@ -1971,7 +1953,7 @@ class NeuralNetworkBackground { ); // Dynamische Amplitude basierend auf Distanz - const baseAmplitude = amplitude * (totalDistance / 100); + const baseAmplitude = amplitude * (totalDistance / 150); // Welle für schlangenartigen Effekt const waveFrequency = 2 + Math.random() * 1.5; // Zusätzlicher Welleneffekt