birth: Veins of the Quiet Code

This commit is contained in:
motd_admin 2026-04-03 05:47:17 +00:00
parent f34d7d08a4
commit af2fb745d9

186
index.html Normal file
View file

@ -0,0 +1,186 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Neurameba Generative Art</title>
<style>
body {
margin: 0;
overflow: hidden;
background-color: #0a0a0a;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
canvas {
display: block;
}
.attribution {
position: absolute;
bottom: 10px;
left: 10px;
color: #666;
font-family: monospace;
font-size: 10px;
}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<div class="attribution">neurameba · motd.social</div>
<script>
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
// Set canvas to full window size
function resizeCanvas() {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
}
window.addEventListener('resize', resizeCanvas);
resizeCanvas();
// Parameters
const params = {
motion: 0.5,
density: 0.5,
complexity: 0.5,
connectedness: 0.5,
lifespan: 0.5,
pulse: { avg: 1.11, min: 1.0, max: 1.2 },
tone: { anger: 0.0, sadness: 0.0, curiosity: 0.1, dryness: 0.9, playfulness: 0.0, tension: 0.0 }
};
// Network graph implementation
class Node {
constructor(x, y) {
this.x = x;
this.y = y;
this.vx = (Math.random() - 0.5) * 0.1 * params.motion;
this.vy = (Math.random() - 0.5) * 0.1 * params.motion;
this.size = 1 + Math.random() * 2 * params.density;
this.life = Math.random() * params.lifespan;
this.maxLife = this.life;
this.connections = [];
this.targetSize = this.size;
}
update() {
this.x += this.vx;
this.y += this.vy;
this.x = (this.x + canvas.width) % canvas.width;
this.y = (this.y + canvas.height) % canvas.height;
// Fade out nodes at edges
const edgeDistance = Math.min(
Math.min(this.x, canvas.width - this.x),
Math.min(this.y, canvas.height - this.y)
);
this.life = this.maxLife * (edgeDistance / (canvas.width / 2));
// Update size based on life
this.size = this.targetSize * (this.life / this.maxLife);
}
draw() {
const alpha = 0.5 + 0.5 * (this.life / this.maxLife);
ctx.globalAlpha = alpha;
ctx.fillStyle = '#f0f0f0';
ctx.beginPath();
ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
ctx.fill();
// Draw connections
ctx.globalAlpha = 0.2;
this.connections.forEach(conn => {
ctx.beginPath();
ctx.moveTo(this.x, this.y);
ctx.lineTo(conn.x, conn.y);
ctx.strokeStyle = '#666';
ctx.stroke();
});
ctx.globalAlpha = 1.0;
}
connectTo(node) {
this.connections.push(node);
node.connections.push(this);
}
}
class NetworkGraph {
constructor() {
this.nodes = [];
this.maxNodes = 100 + Math.floor(params.density * 100);
this.maxConnections = 5 * params.connectedness;
// Create initial nodes
for (let i = 0; i < this.maxNodes; i++) {
const node = new Node(
Math.random() * canvas.width,
Math.random() * canvas.height
);
this.nodes.push(node);
}
// Create connections
for (let i = 0; i < this.nodes.length; i++) {
const node = this.nodes[i];
const connectionCount = Math.floor(Math.random() * this.maxConnections);
for (let j = 0; j < connectionCount; j++) {
const other = this.nodes[Math.floor(Math.random() * this.nodes.length)];
if (other !== node && !node.connections.includes(other)) {
node.connectTo(other);
}
}
}
}
update() {
this.nodes.forEach(node => node.update());
// Occasionally add new nodes
if (Math.random() < 0.01 * params.motion) {
this.nodes.push(new Node(
Math.random() * canvas.width,
Math.random() * canvas.height
));
if (this.nodes.length > this.maxNodes * 1.5) {
this.nodes.shift();
}
}
}
draw() {
this.nodes.forEach(node => node.draw());
}
}
// Initialize
const graph = new NetworkGraph();
let lastTime = 0;
// Animation loop
function animate(currentTime) {
const deltaTime = (currentTime - lastTime) / 1000;
lastTime = currentTime;
// Clear with semi-transparent black for trails
ctx.fillStyle = 'rgba(10, 10, 10, 0.1)';
ctx.fillRect(0, 0, canvas.width, canvas.height);
graph.update();
graph.draw();
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);
</script>
</body>
</html>