birth: Phantom Orbits in Static

This commit is contained in:
motd_admin 2026-04-14 21:47:17 +00:00
parent f84e476ff8
commit 068f95ec0a

132
index.html Normal file
View file

@ -0,0 +1,132 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Chaotic Symmetry</title>
<style>
body {
margin: 0;
overflow: hidden;
background: #0a0a0a;
font-family: 'Courier New', monospace;
color: #444;
}
canvas {
display: block;
}
#attribution {
position: absolute;
bottom: 10px;
right: 10px;
font-size: 8px;
color: #333;
text-shadow: 0 0 2px #000;
}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<div id="attribution">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();
// Strange attractor parameters (Lorenz-like system)
const params = {
a: 10 * (0.3 + 0.7 * 0.588),
b: 28 * (0.3 + 0.7 * 0.588),
c: 8 / (1 + 0.5 * 0.397),
dt: 0.01 * (0.5 + 0.5 * 0.397),
particleCount: Math.max(100, 500 * (0.1 + 0.9 * 0.699)),
trailLength: 50 * (0.2 + 0.8 * (1 - 0.399)),
colorVariation: 0.1 * (1 - 0.9 * 0.90)
};
// Particle system
const particles = Array(params.particleCount).fill().map(() => ({
x: Math.random() * 2 - 1,
y: Math.random() * 2 - 1,
z: Math.random() * 2 - 1,
trail: []
}));
// Animation state
let time = 0;
const baseColor = { r: 200, g: 200, b: 200 };
function updateAttractor(x, y, z) {
const dt = params.dt;
const a = params.a;
const b = params.b;
const c = params.c;
const dx = a * (y - x);
const dy = x * (b - z) - y;
const dz = x * y - c * z;
x += dx * dt;
y += dy * dt;
z += dz * dt;
return { x, y, z };
}
function drawParticle(p) {
// Update attractor position
const pos = updateAttractor(p.x, p.y, p.z);
p.x = pos.x;
p.y = pos.y;
p.z = pos.z;
// Add to trail
p.trail.push({ x: p.x, y: p.y });
if (p.trail.length > params.trailLength) {
p.trail.shift();
}
// Calculate color based on position and time
const hue = (180 + 20 * p.z) % 360;
const saturation = 70 + 10 * Math.sin(time * 0.1);
const lightness = 60 + 10 * Math.sin(time * 0.05 + p.x);
const alpha = 0.8 * (0.5 + 0.5 * Math.sin(time * 0.03 + p.y));
// Draw trail
ctx.strokeStyle = `hsla(${hue}, ${saturation}%, ${lightness}%, ${alpha})`;
ctx.lineWidth = 1 + 0.5 * (1 - params.colorVariation);
ctx.beginPath();
for (let i = 0; i < p.trail.length; i++) {
const point = p.trail[i];
const size = (i / p.trail.length) * 0.5;
const screenX = (point.x * 0.5 + 0.5) * canvas.width;
const screenY = (point.y * 0.5 + 0.5) * canvas.height;
ctx.lineTo(screenX, screenY);
}
ctx.stroke();
}
function animate() {
// Clear with slight fade
ctx.fillStyle = 'rgba(0, 0, 0, 0.1)';
ctx.fillRect(0, 0, canvas.width, canvas.height);
time += 0.01;
// Draw all particles
particles.forEach(drawParticle);
requestAnimationFrame(animate);
}
animate();
</script>
</body>
</html>