Fractal Rain

It’s a grid of shapes that grow and shrink based on where they are. I’ve placed five "hotspots" on the screen; shapes near those spots grow into deep, layered tunnels, while the rest stay as tiny dots.

You can use the sliders to turn the whole thing from sharp, mechanical triangles into soft, organic bubbles.

Log in to post a comment.

// 1. Grid Resolution
const gridRes = 30; // min=10, max=60, step=1
// 2. Base Shape Size (How much of the cell to fill)
const baseSize = 0.9; // min=0.1, max=1.2, step=0.05
// 3. Polygon Sides (3=Triangle, 6=Hexagon, 20+=Circle)
const sides = 6; // min=3, max=10, step=1
// 4. Influence Radius (How far the "bloom" reaches)
const radiusScale = 75; // min=20, max=150, step=1

const turtle = new Turtle();
const depth = 3; 

// Hand-placed spots: [x, y, weight]
// (0,0) is the big main center. The others are "scattered"
const centers = [
    [0, 0, 1.2],      // Main Center (Strongest)
    [-45, 60, 0.7],   // Upper Left-ish
    [70, 20, 0.8],    // Right-ish
    [-20, -75, 0.6],  // Bottom-ish
    [55, -55, 0.7]    // Bottom Right-ish
];

function walk(i) {
    const col = i % gridRes;
    const row = Math.floor(i / gridRes);
    
    const cellSize = 200 / gridRes;
    const x = (col * cellSize) - 100 + (cellSize / 2);
    const y = (row * cellSize) - 100 + (cellSize / 2);
    
    let maxInfluence = 0.05; // The "floor" (small dots in empty space)
    
    centers.forEach(([cx, cy, weight]) => {
        const d = Math.sqrt((x - cx)**2 + (y - cy)**2);
        // Falloff logic
        const influence = Math.max(0, (1 - d / radiusScale) * weight);
        if (influence > maxInfluence) maxInfluence = influence;
    });
    
    // Final radius calculation using the baseSize slider
    const radius = (cellSize / 2) * baseSize * maxInfluence;
    
    if (radius > 0.2) {
        drawFractal(x, y, radius, sides, depth);
    }

    return i < (gridRes * gridRes) - 1;
}

function drawFractal(x, y, radius, s, d) {
    if (d <= 0 || radius < 0.5) return;
    drawPolygon(x, y, radius, s);
    drawFractal(x, y, radius * 0.6, s, d - 1); // 0.6 is the "shrink" factor
}

function drawPolygon(x, y, r, s) {
    const res = s > 20 ? 30 : s; 
    turtle.penup();
    for (let j = 0; j <= res; j++) {
        const a = (j / res) * Math.PI * 2 - Math.PI / 2;
        turtle.goto(x + Math.cos(a) * r, y + Math.sin(a) * r);
        if (j === 0) turtle.pendown();
    }
}