diff --git a/database/systades.db b/database/systades.db index d39f948..7c7d3e5 100644 Binary files a/database/systades.db and b/database/systades.db differ diff --git a/static/neural-network-background.js b/static/neural-network-background.js index 11c3afa..b1b0521 100644 --- a/static/neural-network-background.js +++ b/static/neural-network-background.js @@ -49,35 +49,37 @@ class NeuralNetworkBackground { this.animationFrameId = null; this.isDarkMode = true; // Always use dark mode for the background - // Colors - Updated to be more subtle + // Colors - Updated for intense visibility and neural effect this.darkModeColors = { - background: '#050a14', // Darker blue-black background - nodeColor: '#4a5568', // Darker nodes for subtlety - nodePulse: '#718096', // Subtle blue pulse - connectionColor: '#2d3748', // Darker connections - flowColor: '#4a88ff80' // Semi-transparent flow highlight + background: '#030610', // Noch dunklerer Hintergrund für besseren Kontrast + nodeColor: '#88a5ff', // Hellere, leuchtende Knoten + nodePulse: '#c0d5ff', // Strahlend helles Pulsieren + connectionColor: '#5a6ca8', // Hellere, sichtbarere Verbindungen + flowColor: '#90c8ffee' // Sehr leuchtende, fast undurchsichtige Flüsse }; this.lightModeColors = { background: '#f9fafb', - nodeColor: '#7c3aed', - nodePulse: '#8b5cf6', - connectionColor: '#a78bfa', - flowColor: '#c4b5fd' + nodeColor: '#8c4aff', + nodePulse: '#ab7cff', + connectionColor: '#b798ff', + flowColor: '#d4c5ff' }; - // Config - Updated to be more subtle, efficient, and elegant + // Config - Drastisch verstärkt für strahlende Animationen und neuronale Vernetzung this.config = { - nodeCount: 70, // Reduced node count for better performance - nodeSize: 0.6, // Smaller nodes for subtlety - nodeVariation: 0.3, // Less variation for uniformity - connectionDistance: 150, // Shorter connections for cleaner look - connectionOpacity: 0.15, // More subtle connections - animationSpeed: 0.04, // Slower, more elegant movement - pulseSpeed: 0.002, // Very slow pulse for subtlety - flowSpeed: 0.4, // Slower flow animations - flowDensity: 0.0008, // Less frequent flow animations - flowLength: 0.15 // Shorter flow animations + nodeCount: 120, // Viel mehr Knoten für ein dichtes Netzwerk + nodeSize: 1.4, // Größere Knoten für mehr Sichtbarkeit + nodeVariation: 0.6, // Mehr Variation für organisches Aussehen + connectionDistance: 220, // Deutlich längere Verbindungen für mehr Vernetzung + connectionOpacity: 0.4, // Wesentlich stärkere Verbindungen + animationSpeed: 0.08, // Schnellere Bewegung + pulseSpeed: 0.006, // Schnelleres Pulsieren für lebendiges Aussehen + flowSpeed: 0.8, // Schnellere Flussanimationen + flowDensity: 0.005, // Viel mehr Flussanimationen + flowLength: 0.25, // Längere Flussanimationen + maxConnections: 6, // NEW: Neue Eigenschaft für mehr neuronale Verbindungen pro Knoten + clusteringFactor: 0.3 // NEW: Erzeugt Cluster wie in einem neuronalen Netzwerk }; // Initialize @@ -221,18 +223,60 @@ class NeuralNetworkBackground { const width = this.canvas.width / (window.devicePixelRatio || 1); const height = this.canvas.height / (window.devicePixelRatio || 1); - // Create nodes with random positions and properties - for (let i = 0; i < this.config.nodeCount; i++) { - const node = { + // Erstelle Cluster-Zentren für neuronale Netzwerkmuster + const clusterCount = Math.floor(5 + Math.random() * 4); // 5-8 Cluster + const clusters = []; + + for (let i = 0; i < clusterCount; i++) { + clusters.push({ x: Math.random() * width, y: Math.random() * height, - size: this.config.nodeSize + Math.random() * this.config.nodeVariation, + radius: 100 + Math.random() * 150 + }); + } + + // Create nodes with random positions and properties + for (let i = 0; i < this.config.nodeCount; i++) { + // Entscheide, ob dieser Knoten zu einem Cluster gehört oder nicht + const useCluster = Math.random() < this.config.clusteringFactor; + let x, y; + + if (useCluster && clusters.length > 0) { + // Wähle ein zufälliges Cluster + const cluster = clusters[Math.floor(Math.random() * clusters.length)]; + const angle = Math.random() * Math.PI * 2; + const distance = Math.random() * cluster.radius; + + // Platziere in der Nähe des Clusters mit einiger Streuung + x = cluster.x + Math.cos(angle) * distance; + y = cluster.y + Math.sin(angle) * distance; + + // Stelle sicher, dass es innerhalb des Bildschirms bleibt + x = Math.max(0, Math.min(width, x)); + y = Math.max(0, Math.min(height, y)); + } else { + // Zufällige Position außerhalb von Clustern + x = Math.random() * width; + y = Math.random() * height; + } + + // Bestimme die Knotengröße - wichtigere Knoten (in Clustern) sind größer + const nodeImportance = useCluster ? 1.2 : 0.8; + const size = this.config.nodeSize * nodeImportance + Math.random() * this.config.nodeVariation; + + const node = { + x: x, + y: y, + size: size, speed: { x: (Math.random() - 0.5) * this.config.animationSpeed, y: (Math.random() - 0.5) * this.config.animationSpeed }, pulsePhase: Math.random() * Math.PI * 2, // Random starting phase - connections: [] + connections: [], + isActive: Math.random() < 0.3, // Some nodes start active for neural firing effect + lastFired: 0, // For neural firing animation + firingRate: 1000 + Math.random() * 4000 // Random firing rate in ms }; this.nodes.push(node); @@ -248,23 +292,60 @@ class NeuralNetworkBackground { const nodeA = this.nodes[i]; nodeA.connections = []; - for (let j = i + 1; j < this.nodes.length; j++) { + // Sortiere andere Knoten nach Entfernung für bevorzugte nahe Verbindungen + const potentialConnections = []; + + for (let j = 0; j < this.nodes.length; j++) { + if (i === j) continue; + const nodeB = this.nodes[j]; const dx = nodeB.x - nodeA.x; const dy = nodeB.y - nodeA.y; const distance = Math.sqrt(dx * dx + dy * dy); if (distance < this.config.connectionDistance) { + potentialConnections.push({ + index: j, + distance: distance + }); + } + } + + // Sortiere nach Entfernung + potentialConnections.sort((a, b) => a.distance - b.distance); + + // Wähle die nächsten N Verbindungen, maximal maxConnections + const maxConn = Math.min( + this.config.maxConnections, + potentialConnections.length, + 1 + Math.floor(Math.random() * this.config.maxConnections) + ); + + for (let c = 0; c < maxConn; c++) { + const connection = potentialConnections[c]; + const j = connection.index; + const nodeB = this.nodes[j]; + const distance = connection.distance; + + // Create weighted connection (closer = stronger) + const connectionStrength = Math.max(0, 1 - distance / this.config.connectionDistance); + const connOpacity = connectionStrength * this.config.connectionOpacity; + + // Check if connection already exists + if (!this.connections.some(conn => + (conn.from === i && conn.to === j) || (conn.from === j && conn.to === i) + )) { // Create connection - const connection = { + this.connections.push({ from: i, to: j, distance: distance, - opacity: Math.max(0, 1 - distance / this.config.connectionDistance) * this.config.connectionOpacity, - hasFlow: false // Each connection can have a flow - }; + opacity: connOpacity, + strength: connectionStrength, + hasFlow: false, // Each connection can have a flow + lastActivated: 0 // For neural firing animation + }); - this.connections.push(connection); nodeA.connections.push(j); nodeB.connections.push(i); } @@ -280,42 +361,48 @@ class NeuralNetworkBackground { // Update nodes const width = this.canvas.width / (window.devicePixelRatio || 1); const height = this.canvas.height / (window.devicePixelRatio || 1); + const now = Date.now(); - // Update node positions - slower, more flowing movement + // Simulate neural firing for (let i = 0; i < this.nodes.length; i++) { const node = this.nodes[i]; - // Move node with slight randomness for organic feel - node.speed.x += (Math.random() - 0.5) * 0.001; - node.speed.y += (Math.random() - 0.5) * 0.001; - - // Dampen speeds for stability - node.speed.x *= 0.99; - node.speed.y *= 0.99; - - // Apply speed limits - node.speed.x = Math.max(-this.config.animationSpeed, Math.min(this.config.animationSpeed, node.speed.x)); - node.speed.y = Math.max(-this.config.animationSpeed, Math.min(this.config.animationSpeed, node.speed.y)); - - // Move node - node.x += node.speed.x; - node.y += node.speed.y; - - // Boundary check with smooth bounce - if (node.x < 0 || node.x > width) { - node.speed.x *= -0.8; // Softer bounce - node.x = Math.max(0, Math.min(node.x, width)); - } - - if (node.y < 0 || node.y > height) { - node.speed.y *= -0.8; // Softer bounce - node.y = Math.max(0, Math.min(node.y, height)); - } - - // Update pulse phase - node.pulsePhase += this.config.pulseSpeed; - if (node.pulsePhase > Math.PI * 2) { - node.pulsePhase -= Math.PI * 2; + // Check if node should fire based on its firing rate + if (now - node.lastFired > node.firingRate) { + node.isActive = true; + node.lastFired = now; + + // Activate connected nodes with probability based on connection strength + for (const connIndex of node.connections) { + // Find the connection + const conn = this.connections.find(c => + (c.from === i && c.to === connIndex) || (c.from === connIndex && c.to === i) + ); + + if (conn) { + // Mark connection as recently activated + conn.lastActivated = now; + + // Create a flow along this connection + if (Math.random() < conn.strength * 0.8) { + this.flows.push({ + connection: conn, + progress: 0, + direction: conn.from === i, // Flow from activated node + length: this.config.flowLength + Math.random() * 0.1, + intensity: 0.7 + Math.random() * 0.3 // Random intensity for variation + }); + } + + // Probability for connected node to activate + if (Math.random() < conn.strength * 0.5) { + this.nodes[connIndex].isActive = true; + this.nodes[connIndex].lastFired = now - Math.random() * 500; // Slight variation + } + } + } + } else if (now - node.lastFired > 300) { // Deactivate after short period + node.isActive = false; } } @@ -355,6 +442,11 @@ class NeuralNetworkBackground { this.flows.splice(i, 1); } } + + // Generate more flows for enhanced visibility + if (Math.random() < this.config.flowDensity * 2) { + this.createNewFlow(); + } } // New method to create flow animations @@ -416,14 +508,30 @@ class NeuralNetworkBackground { const positions = new Float32Array(this.nodes.length * 2); const sizes = new Float32Array(this.nodes.length); + const now = Date.now(); + for (let i = 0; i < this.nodes.length; i++) { const node = this.nodes[i]; positions[i * 2] = node.x; positions[i * 2 + 1] = node.y; - // Size with subtle pulse effect - const pulse = Math.sin(node.pulsePhase) * 0.2 + 1; - sizes[i] = node.size * pulse * (node.connections.length > 3 ? 1.3 : 1); + // Enhanced pulse effect with additional boost for active nodes + let pulse = Math.sin(node.pulsePhase) * 0.4 + 1; + + // Make active nodes pulse more intensely (neural firing effect) + if (node.isActive) { + const timeSinceFired = now - node.lastFired; + if (timeSinceFired < 300) { + // Quick expand then contract effect + const normalizedTime = timeSinceFired / 300; + const fireBoost = 1.5 * (1 - normalizedTime); + pulse += fireBoost; + } + } + + // Nodes with more connections are larger (hub neurons) + const connectivityFactor = 1 + (node.connections.length / this.config.maxConnections) * 0.8; + sizes[i] = node.size * pulse * connectivityFactor; } // Bind position buffer @@ -452,24 +560,45 @@ class NeuralNetworkBackground { ); this.gl.enableVertexAttribArray(this.programInfo.attribLocations.pointSize); - // Set node color - more subtle - const colorObj = this.isDarkMode ? this.darkModeColors : this.lightModeColors; - const nodeColor = this.hexToRgb(colorObj.nodeColor); - this.gl.uniform4f( - this.programInfo.uniformLocations.color, - nodeColor.r / 255, - nodeColor.g / 255, - nodeColor.b / 255, - 0.7 // Lower opacity for subtlety - ); - - // Draw nodes + // Enable blending for all nodes this.gl.enable(this.gl.BLEND); this.gl.blendFunc(this.gl.SRC_ALPHA, this.gl.ONE); // Additive blending for glow - this.gl.drawArrays(this.gl.POINTS, 0, this.nodes.length); + + // Draw each node individually with its own color + for (let i = 0; i < this.nodes.length; i++) { + const node = this.nodes[i]; + + // Set node color - more visible with active highlighting + const colorObj = this.isDarkMode ? this.darkModeColors : this.lightModeColors; + const nodeColor = this.hexToRgb(colorObj.nodeColor); + const nodePulseColor = this.hexToRgb(colorObj.nodePulse); + + // Use pulse color for active nodes + let r = nodeColor.r / 255; + let g = nodeColor.g / 255; + let b = nodeColor.b / 255; + + // Active nodes get brighter color + if (node.isActive) { + r = (r + nodePulseColor.r / 255) / 2; + g = (g + nodePulseColor.g / 255) / 2; + b = (b + nodePulseColor.b / 255) / 2; + } + + this.gl.uniform4f( + this.programInfo.uniformLocations.color, + r, g, b, + 0.95 // Higher opacity for maximum visibility + ); + + // Draw each node individually for better control + this.gl.drawArrays(this.gl.POINTS, i, 1); + } } renderConnectionsWebGL() { + const now = Date.now(); + // For each connection, draw a line for (const connection of this.connections) { const fromNode = this.nodes[connection.from]; @@ -497,15 +626,28 @@ class NeuralNetworkBackground { // Disable point size attribute for lines this.gl.disableVertexAttribArray(this.programInfo.attribLocations.pointSize); - // Set line color with connection opacity - darker, more subtle + // Set line color with connection opacity const colorObj = this.isDarkMode ? this.darkModeColors : this.lightModeColors; - const lineColor = this.hexToRgb(colorObj.connectionColor); + let lineColor = this.hexToRgb(colorObj.connectionColor); + + // Highlight recently activated connections for neural pathway effect + let opacity = connection.opacity * 1.4; // Base increased visibility + + if (now - connection.lastActivated < 800) { + // Make recently activated connections brighter + lineColor = this.hexToRgb(colorObj.flowColor); + + // Fade out effect + const timeFactor = 1 - ((now - connection.lastActivated) / 800); + opacity = Math.max(opacity, timeFactor * 0.9); + } + this.gl.uniform4f( this.programInfo.uniformLocations.color, lineColor.r / 255, lineColor.g / 255, lineColor.b / 255, - connection.opacity * 0.8 // Reduced for subtlety + opacity ); // Draw the line @@ -585,7 +727,7 @@ class NeuralNetworkBackground { 1 ); - // Flow color - subtle glow + // Flow color - much stronger glow const colorObj = this.isDarkMode ? this.darkModeColors : this.lightModeColors; const flowColor = this.hexToRgb(colorObj.flowColor); this.gl.uniform4f( @@ -593,13 +735,13 @@ class NeuralNetworkBackground { flowColor.r / 255, flowColor.g / 255, flowColor.b / 255, - 0.4 * fadeOpacity // Subtle flow opacity + 0.9 * fadeOpacity * flow.intensity // Much stronger flow opacity with intensity variation ); // Draw the flow line this.gl.enable(this.gl.BLEND); this.gl.blendFunc(this.gl.SRC_ALPHA, this.gl.ONE); - this.gl.lineWidth(1.5); // Slightly thicker for visibility + this.gl.lineWidth(2.5); // Even thicker for dramatic visibility this.gl.drawArrays(this.gl.LINES, 0, 2); } } diff --git a/website/database/systades.db b/website/database/systades.db deleted file mode 100644 index 7ceb056..0000000 Binary files a/website/database/systades.db and /dev/null differ