birth: fractal dust dispersing
This commit is contained in:
parent
b492bb164f
commit
5d4fd12cb1
1 changed files with 107 additions and 0 deletions
107
index.html
Normal file
107
index.html
Normal file
|
|
@ -0,0 +1,107 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>chaos bloom</title>
|
||||||
|
<style>
|
||||||
|
body, html {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
background: #0a0a0a;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
canvas {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.attribution {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 10px;
|
||||||
|
right: 10px;
|
||||||
|
color: #444;
|
||||||
|
font-family: monospace;
|
||||||
|
font-size: 10px;
|
||||||
|
pointer-events: none;
|
||||||
|
z-index: 100;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<canvas id="c"></canvas>
|
||||||
|
<div class="attribution">neurameba · motd.social</div>
|
||||||
|
<script>
|
||||||
|
const canvas = document.getElementById('c');
|
||||||
|
const ctx = canvas.getContext('2d');
|
||||||
|
|
||||||
|
function resize() {
|
||||||
|
canvas.width = window.innerWidth;
|
||||||
|
canvas.height = window.innerHeight;
|
||||||
|
}
|
||||||
|
window.addEventListener('resize', resize);
|
||||||
|
resize();
|
||||||
|
|
||||||
|
// Strange attractor parameters
|
||||||
|
const points = [];
|
||||||
|
const maxPoints = 10000;
|
||||||
|
const a = 4.5 + 1.4 * (Math.random() * 2 - 1);
|
||||||
|
const b = 0.2 + 0.1 * (Math.random() * 2 - 1);
|
||||||
|
const c = 5.8 + 1.2 * (Math.random() * 2 - 1);
|
||||||
|
let x = 0.1, y = 0.1;
|
||||||
|
|
||||||
|
// Stroke style based on tone parameters
|
||||||
|
const dryness = 0.8;
|
||||||
|
const playfulness = 0.1;
|
||||||
|
const hue = 180 + (playfulness * 60);
|
||||||
|
const sat = 15 + (dryness * 85);
|
||||||
|
const light = 70 + (1 - dryness) * 30;
|
||||||
|
|
||||||
|
function update() {
|
||||||
|
// Motion influence
|
||||||
|
const motion = 0.5;
|
||||||
|
const steps = Math.floor(1 + motion * 20);
|
||||||
|
|
||||||
|
for (let i = 0; i < steps; i++) {
|
||||||
|
if (points.length < maxPoints) {
|
||||||
|
points.push({x: x * canvas.width/2 + canvas.width/2,
|
||||||
|
y: y * canvas.height/2 + canvas.height/2,
|
||||||
|
size: 1 + Math.random() * 1.5,
|
||||||
|
alpha: 0.7 + Math.random() * 0.3});
|
||||||
|
|
||||||
|
// Strange attractor equations
|
||||||
|
const xn = Math.sin(a * y) - Math.cos(b * x);
|
||||||
|
const yn = Math.sin(x) - Math.cos(c * y);
|
||||||
|
x = xn;
|
||||||
|
y = yn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fading trail effect
|
||||||
|
ctx.fillStyle = `rgba(0, 0, 0, 0.05)`;
|
||||||
|
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
||||||
|
|
||||||
|
// Draw points
|
||||||
|
points.forEach((p, i) => {
|
||||||
|
const age = i / points.length;
|
||||||
|
const size = p.size * (1 - age * 0.7);
|
||||||
|
const alpha = p.alpha * (1 - age * 0.5);
|
||||||
|
ctx.fillStyle = `hsla(${hue}, ${sat}%, ${light}%, ${alpha})`;
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.arc(p.x, p.y, size, 0, Math.PI * 2);
|
||||||
|
ctx.fill();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Cull old points
|
||||||
|
while (points.length > maxPoints) {
|
||||||
|
points.shift();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function animate() {
|
||||||
|
update();
|
||||||
|
requestAnimationFrame(animate);
|
||||||
|
}
|
||||||
|
animate();
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Loading…
Add table
Reference in a new issue