fractal-drift-through-stati.../index.html

116 lines
No EOL
3.2 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Fractal Drift</title>
<style>
body {
margin: 0;
overflow: hidden;
background: #0a0a0a;
font-family: 'Courier New', monospace;
color: #666;
}
#attribution {
position: absolute;
bottom: 10px;
right: 10px;
font-size: 10px;
opacity: 0.5;
}
</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
const params = {
a: 2.0,
b: 0.5,
c: -1.0,
d: -0.5,
e: 1.0,
x: 0.1,
y: 0.1,
scale: 30,
hue: 0,
hueSpeed: 0.01
};
const points = [];
const maxPoints = 2000;
const trails = [];
function draw() {
ctx.fillStyle = 'rgba(0, 0, 0, 0.1)';
ctx.fillRect(0, 0, canvas.width, canvas.height);
const newPoint = {
x: Math.sin(params.a * params.y) - Math.cos(params.b * params.x),
y: Math.sin(params.c * params.x) - Math.cos(params.d * params.y),
hue: params.hue
};
params.hue = (params.hue + params.hueSpeed) % 360;
// Update attractor parameters
params.x = newPoint.x;
params.y = newPoint.y;
// Scale and position
const px = canvas.width/2 + newPoint.x * params.scale;
const py = canvas.height/2 + newPoint.y * params.scale;
points.push({x: px, y: py, hue: newPoint.hue});
if (points.length > maxPoints) {
points.shift();
}
// Draw trails
trails.push([...points]);
if (trails.length > 30) {
trails.shift();
}
// Draw fading trails
trails.forEach((trail, i) => {
const alpha = i / trails.length;
const hue = trail[0].hue;
ctx.strokeStyle = `hsl(${hue}, 100%, 80%, ${alpha})`;
ctx.lineWidth = 1;
ctx.beginPath();
trail.forEach((p, j) => {
if (j === 0) ctx.moveTo(p.x, p.y);
else ctx.lineTo(p.x, p.y);
});
ctx.stroke();
});
// Add occasional glitches based on pulse
if (Math.random() < 0.02) {
params.scale *= 1.1;
setTimeout(() => { params.scale /= 1.1; }, 50);
}
requestAnimationFrame(draw);
}
draw();
</script>
</body>
</html>