JSFiddle - React, Tailwind, and code Playground

by John Doe

HTML

<p>Load an image: <input type='file' onchange='loadImage(this)'></p>
<div id='wrapper'>
    <canvas id='image' width='100' height='100'>Your browser doesn't support the HTML5 canvas tag.</canvas>
    <p><input id='chebyshev' type='checkbox'> Chebyshev</p>
    <p id='coords'></p>
</div>
<p>(Images larger than 200&times;200 are not advised. Only tested in Chrome.)</p>

CSS

* {
    font-size: 100%;
    font-family: Arial, sans-serif;
}
#wrapper {
    display: none;
}

JavaScript

var img, ctxRead, ctxWrite, whites

function loadImage(input) {
    if (input.files && input.files[0]) {
        var reader = new FileReader()
        reader.onload = function(e) {
            img = $('<img>').attr('src', e.target.result)[0]
            function setupCanvas(canvas) {
      			canvas.attr('width', img.width)
      			canvas.attr('height', img.height)
				var ctx = canvas[0].getContext('2d')
                ctx.drawImage(img, 0, 0)
				return ctx
            }
            ctxWrite = setupCanvas($('#image'))
            ctxRead = setupCanvas($('<canvas>'))
            $('#wrapper').show()
            findWhites()
		}
        reader.readAsDataURL(input.files[0])
    }
}

function getMousePos(e, obj) {
    var curLeft = 0, curTop = 0
    if (obj.offsetParent) {
        do {
            curLeft += obj.offsetLeft
            curTop += obj.offsetTop
        } while (obj = obj.offsetParent)
    }
    return {x: e.pageX - curLeft, y: e.pageY - curTop}
}

function getPixel(x, y) {
	return ctxRead.getImageData(x, y, 1, 1).data  
}

function setPixel(x, y, color) {
    ctxWrite.fillStyle = 'rgb(' + color[0] + ',' + color[1] + ',' + color[2] + ')'
    ctxWrite.fillRect(x, y, 1, 1)
}

function findWhites() {
    whites = new Array(img.width)
    for (var x = 0; x < img.width; x++) {
		whites[x] = new Array(img.height)
        for (var y = 0; y < img.height; y++) {
            var color = getPixel(x, y)
        	whites[x][y] = color[0] == 255 && color[1] == 255 && color[2] == 255
        }
    }
}
    
function w(x, y) {
	return whites[x][y]   
}
    
function distBasedColor(x, y) {
    var q = new Queue(), visited = {}, maxDist = 0
    q.enqueue([x, y, 0])
    while (!q.isEmpty()) {
    	var p = q.dequeue(), x = p[0], y = p[1], d = p[2], key = img.width * y + x
        if (!visited.hasOwnProperty(key)) {
            visited[key] = d
            if (d > maxDist)
                maxDist = d
            var e = function(x, y) { q.enqueue([x, y, d + 1]) }
         ...