Update neural network background animation: Enhance color visibility and node dynamics for improved visual effects. Introduce clustering for node positioning and optimize connection rendering with increased opacity and strength. Remove old database file and update systades.db for better data management.
This commit is contained in:
Binary file not shown.
@@ -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;
|
||||
// Check if node should fire based on its firing rate
|
||||
if (now - node.lastFired > node.firingRate) {
|
||||
node.isActive = true;
|
||||
node.lastFired = now;
|
||||
|
||||
// Dampen speeds for stability
|
||||
node.speed.x *= 0.99;
|
||||
node.speed.y *= 0.99;
|
||||
// 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)
|
||||
);
|
||||
|
||||
// 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));
|
||||
if (conn) {
|
||||
// Mark connection as recently activated
|
||||
conn.lastActivated = now;
|
||||
|
||||
// Move node
|
||||
node.x += node.speed.x;
|
||||
node.y += node.speed.y;
|
||||
// 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
|
||||
});
|
||||
}
|
||||
|
||||
// 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;
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user