Voronoi Diagram using DOM

by Anton

HTML

<div id="diagram"></div>

CSS

#diagram {
    position: relative;
    margin: 10px;
    width: 300px;
    height: 300px;
    border: solid 3px lightgrey;
}

.pixel {
    display: block;
    float: left;
    height: 1px;
    width: 1px;
    margin: 0;
}

.first {
    clear: left;
}

.anchor {
    position: absolute;
    display: block;
    height: 7px;
    width: 7px;
    margin-top: -3px;
    margin-left: -3px;
    border-radius: 50%;
    z-index: 100;
}

JavaScript

var w = $('#diagram').width() - 1,
    h = $('#diagram').height() - 1,
    html = '',
    maxAnchors = 30,
    anchors = [];

// Generate random anchors
for(var i = 0; i < maxAnchors; i++) {
    var newAnchor = {
        x: Math.random() * w,
        y: Math.random() * h,
        hue: i * 255 / maxAnchors
    };
    
    anchors.push(newAnchor);
    
    // Drawing the anchors
    /*html += '<span class="anchor" style="top:' + (h - newAnchor.y)
        +'px;left:' + (newAnchor.x)
        + 'px;background-color:hsl(' + newAnchor.hue
        + ',100%,50%);"></span>';*/
}

for(var i = 0; i < h; i++) {
    // Draw row (separated by '.first' pixel
    for(var j = 0; j < w; j++) {
        // Draw pixel
        html += '<span class="pixel' + (j == 0 ? ' first' : '') 
        + '" style="background-color: ' + getColour({x: j, y: h-i}, anchors) 
        + '"></span>';
    }
}

$('#diagram').append(html);

// Returns colour of pixel based on its offset
//   from the closest anchor
function getColour(point, anchors) {
    var closestAnchorInd,
        maxDist = 0,
        closestDist;
    
    for(var i = 0; i < anchors.length; i++) {
        var currDist = dist(point, anchors[i]);
        if(!closestDist || currDist < closestDist) {
            closestDist = currDist;
            closestAnchorInd = i;
        }
        //maxDist = Math.max(maxDist, currDist);
    }
    
    return 'hsl(' + anchors[closestAnchorInd].hue + ',60%,60%)';
        //',' + (50 + closestDist * 50 / maxDist) + '%,50%)';
}

function dist(point1, point2) {
    var dx = point1.x - point2.x,
        dy = point1.y - point2.y;
    
    return Math.sqrt(dx*dx + dy*dy);
}