Circle Art

An attempt at recreating http://scratch.mit.edu/projects/47084300/ in javascript. :)

by Josh Pullen

HTML

<canvas id="canvas"></canvas>

CSS

#canvas {
    border:1px solid #ddd;
}

JavaScript

var canvas = document.getElementById("canvas"),
    ctx = canvas.getContext("2d");

canvas.width = 480;
canvas.height = 360;

var dots = [];

// TODO: Prevent overflow when there isn't any space left
function dotIsOkay(x, y, radius) {
    if(radius < x - 3 && radius + 3 < canvas.width - x && radius + 3 < y && radius + 3 < canvas.height - y) {
        // Dot is within canvas
        // Now check that dot is not touching other dots
        for (i = 0; i < dots.length; i++) {
            // For each dot, use distance formula to determine whether the dot is within another dot.
            // Min distance allowed is determined by adding the two radiuses together and adding an additional 3px for spacing
            if (Math.sqrt( Math.pow( dots[i].x - x, 2) + Math.pow( dots[i].y - y, 2) ) < dots[i].radius + radius + 3) {
                // Within another circle
                return false;
            }
        }
        
        // Not in any circles
        return true;
        
    } else {
        // Dot is outside canvas
        return false;
    }
}

function addDot() {
    var dotData = {
        x:0,
        y:0,
        radius:5,
        color: "#000"
    };
    
    while ( !dotIsOkay(dotData.x, dotData.y, 5) ) {
        dotData.x = Math.random() * canvas.width;
        dotData.y = Math.random() * canvas.height;
    }
    
    while ( dotIsOkay(dotData.x, dotData.y, dotData.radius) && dotData.radius < 35 ) {
           dotData.radius = dotData.radius + 1;
    }
    // TODO: randomize colors
    dots.push(dotData);
}

function render() {
    canvas.width = canvas.width; // Clears canvas
    
    for (id = 0; id < dots.length; id++) {
        ctx.beginPath();
        ctx.arc(dots[id].x, dots[id].y, dots[id].radius, 0, 2 * Math.PI, false);
        ctx.fillStyle = dots[id].color;
        ctx.fill();
    }
}

for (i = 0; i < 200 ; i++) {
    addDot();
}

render();

console.log(dots);