birth: ) &&
html.includes(
This commit is contained in:
parent
8d9785d87f
commit
4ebb6895fd
1 changed files with 221 additions and 0 deletions
221
index.html
Normal file
221
index.html
Normal file
|
|
@ -0,0 +1,221 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Mutating Network</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
background: #0a0a0a;
|
||||||
|
font-family: 'Courier New', monospace;
|
||||||
|
}
|
||||||
|
canvas {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
#info {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 10px;
|
||||||
|
left: 10px;
|
||||||
|
color: #555;
|
||||||
|
font-size: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<canvas id="canvas"></canvas>
|
||||||
|
<div id="info">neurameba · motd.social</div>
|
||||||
|
<script>
|
||||||
|
const canvas = document.getElementById('canvas');
|
||||||
|
const ctx = canvas.getContext('2d');
|
||||||
|
|
||||||
|
function resizeCanvas() {
|
||||||
|
canvas.width = window.innerWidth;
|
||||||
|
canvas.height = window.innerHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener('resize', resizeCanvas);
|
||||||
|
resizeCanvas();
|
||||||
|
|
||||||
|
// Parameters from prompt
|
||||||
|
const params = {
|
||||||
|
motion: 0.481,
|
||||||
|
density: 0.314,
|
||||||
|
complexity: 0.832,
|
||||||
|
connectedness: 0.648,
|
||||||
|
lifespan: 0.418,
|
||||||
|
pulse: { avg: 0.35, min: 0.30, max: 1.20 },
|
||||||
|
tone: { anger: 0.00, sadness: 0.00, curiosity: 0.70, dryness: 0.90, playfulness: 0.00, tension: 0.00 },
|
||||||
|
topology: {
|
||||||
|
nodes: 7,
|
||||||
|
branches: 7,
|
||||||
|
loops: 61,
|
||||||
|
maxDepth: 7,
|
||||||
|
thicknessRatio: 1.00,
|
||||||
|
fractalDim: 0.500,
|
||||||
|
energy: 42.2
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Generate network graph
|
||||||
|
class Node {
|
||||||
|
constructor(x, y) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
this.vx = 0;
|
||||||
|
this.vy = 0;
|
||||||
|
this.targetX = x;
|
||||||
|
this.targetY = y;
|
||||||
|
this.size = 2 + Math.random() * 3;
|
||||||
|
this.energy = params.topology.energy / params.topology.nodes;
|
||||||
|
this.connections = [];
|
||||||
|
this.pulse = params.pulse.min + Math.random() * (params.pulse.max - params.pulse.min);
|
||||||
|
}
|
||||||
|
|
||||||
|
addConnection(node) {
|
||||||
|
this.connections.push(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
update() {
|
||||||
|
// Add some movement based on motion parameter
|
||||||
|
const moveFactor = params.motion * 0.5;
|
||||||
|
this.vx += (this.targetX - this.x) * 0.01 * moveFactor;
|
||||||
|
this.vy += (this.targetY - this.y) * 0.01 * moveFactor;
|
||||||
|
this.vx *= 0.9;
|
||||||
|
this.vy *= 0.9;
|
||||||
|
|
||||||
|
this.x += this.vx;
|
||||||
|
this.y += this.vy;
|
||||||
|
|
||||||
|
// Add pulse effect
|
||||||
|
this.pulse += (params.pulse.avg - this.pulse) * 0.01;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Network {
|
||||||
|
constructor() {
|
||||||
|
this.nodes = [];
|
||||||
|
this.time = 0;
|
||||||
|
this.createGraph();
|
||||||
|
}
|
||||||
|
|
||||||
|
createGraph() {
|
||||||
|
// Create nodes with positions
|
||||||
|
for (let i = 0; i < params.topology.nodes; i++) {
|
||||||
|
const angle = (i / params.topology.nodes) * Math.PI * 2;
|
||||||
|
const distance = Math.min(canvas.width, canvas.height) * 0.4;
|
||||||
|
const x = canvas.width/2 + Math.cos(angle) * distance;
|
||||||
|
const y = canvas.height/2 + Math.sin(angle) * distance;
|
||||||
|
this.nodes.push(new Node(x, y));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create connections based on connectedness
|
||||||
|
const connections = [];
|
||||||
|
for (let i = 0; i < this.nodes.length; i++) {
|
||||||
|
for (let j = i+1; j < this.nodes.length; j++) {
|
||||||
|
if (Math.random() < params.connectedness) {
|
||||||
|
connections.push([i, j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adjust number of connections to match topology
|
||||||
|
while (connections.length > params.topology.branches) {
|
||||||
|
connections.splice(Math.floor(Math.random() * connections.length), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the actual connections
|
||||||
|
connections.forEach(([i, j]) => {
|
||||||
|
this.nodes[i].addConnection(this.nodes[j]);
|
||||||
|
this.nodes[j].addConnection(this.nodes[i]);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add some loops
|
||||||
|
for (let i = 0; i < params.topology.loops; i++) {
|
||||||
|
if (this.nodes.length > 2) {
|
||||||
|
const a = Math.floor(Math.random() * this.nodes.length);
|
||||||
|
const b = Math.floor(Math.random() * this.nodes.length);
|
||||||
|
const c = Math.floor(Math.random() * this.nodes.length);
|
||||||
|
if (a !== b && b !== c && a !== c) {
|
||||||
|
this.nodes[b].addConnection(this.nodes[a]);
|
||||||
|
this.nodes[c].addConnection(this.nodes[b]);
|
||||||
|
this.nodes[a].addConnection(this.nodes[c]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
update() {
|
||||||
|
this.time += 0.01;
|
||||||
|
|
||||||
|
// Update nodes
|
||||||
|
this.nodes.forEach(node => {
|
||||||
|
node.update();
|
||||||
|
|
||||||
|
// Add some noise based on motion
|
||||||
|
node.x += Math.sin(this.time * 2 + node.x * 0.01) * 0.5 * params.motion;
|
||||||
|
node.y += Math.cos(this.time * 2 + node.y * 0.01) * 0.5 * params.motion;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Update connections
|
||||||
|
this.nodes.forEach(node => {
|
||||||
|
node.connections.forEach(conn => {
|
||||||
|
// Make connections thicker based on energy
|
||||||
|
conn.thickness = params.topology.thicknessRatio * (conn.energy / (this.nodes.length * 10));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
draw() {
|
||||||
|
// Clear with semi-transparent for motion trails
|
||||||
|
ctx.fillStyle = 'rgba(10, 10, 10, 0.05)';
|
||||||
|
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
||||||
|
|
||||||
|
// Draw connections
|
||||||
|
ctx.lineWidth = 0.5;
|
||||||
|
ctx.strokeStyle = `hsl(180, ${params.tone.dryness * 10}%, ${params.tone.dryness * 80 + 20}%)`;
|
||||||
|
|
||||||
|
this.nodes.forEach(node => {
|
||||||
|
node.connections.forEach(conn => {
|
||||||
|
const alpha = params.tone.dryness * 0.8 + 0.2;
|
||||||
|
ctx.globalAlpha = alpha;
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(node.x, node.y);
|
||||||
|
ctx.lineTo(conn.x, conn.y);
|
||||||
|
ctx.stroke();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Draw nodes
|
||||||
|
ctx.globalAlpha = 1;
|
||||||
|
this.nodes.forEach(node => {
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.arc(node.x, node.y, node.size, 0, Math.PI * 2);
|
||||||
|
|
||||||
|
// Color based on tone parameters
|
||||||
|
const hue = 180; // teal for curiosity
|
||||||
|
const saturation = params.tone.dryness * 50 + 10;
|
||||||
|
const lightness = 60 + Math.sin(this.time * 0.5 + node.x * 0.01) * 10;
|
||||||
|
ctx.fillStyle = `hsl(${hue}, ${saturation}%, ${lightness}%)`;
|
||||||
|
ctx.fill();
|
||||||
|
|
||||||
|
ctx.strokeStyle = `hsl(${hue}, ${saturation * 0.7}%, ${lightness * 0.7}%)`;
|
||||||
|
ctx.lineWidth = 0.5;
|
||||||
|
ctx.stroke();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const network = new Network();
|
||||||
|
|
||||||
|
function animate() {
|
||||||
|
network.update();
|
||||||
|
network.draw();
|
||||||
|
requestAnimationFrame(animate);
|
||||||
|
}
|
||||||
|
|
||||||
|
animate();
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Loading…
Add table
Reference in a new issue