JSFiddle - React, Tailwind, and code Playground

by Lachlan Arthur

HTML

<canvas id="input" width="500" height="300"></canvas>
<canvas id="output" width="500" height="300"></canvas>

CSS

#input {
    position: absolute;
    left: -1000px;
}
#output {
    position: relative;
}

JavaScript

function $(e) {
    return document.querySelector(e);
}

var canvas_input = $("#input");
var ctx_input = canvas_input.getContext("2d");

ctx_input.fillStyle = "#fff";
ctx_input.fillRect(0, 0, canvas_input.width, canvas_input.height);
ctx_input.fillStyle = "#000";
ctx_input.font = "200px impact";
ctx_input.fillText("Spot", 50, 200);

var canvas_output = $("#output");
var ctx_output = canvas_output.getContext("2d");

function draw_output(mouseX, mouseY) {
    ctx_output.fillStyle = "#fff";
    ctx_output.fillRect(0, 0, canvas_output.width, canvas_output.height);
    ctx_output.fillStyle = "#000";
    for (var x = 0; x < canvas_output.width; x += 10) {
        for (var y = 0; y < canvas_output.height; y += 10) {
            var pixel = ctx_input.getImageData(x, y, 1, 1);
            if (pixel.data[0] == 0 &&
                pixel.data[1] == 0 &&
                pixel.data[2] == 0 &&
                pixel.data[3] == 255) {
                var minSize = 2.5;
                var maxSize = 7;
                var size = maxSize-(Math.sqrt(Math.pow(mouseX-x, 2)+Math.pow(mouseY-y, 2))/20);
                size = size < minSize ? minSize : size;
                ctx_output.fillStyle = "rgba(" +
                    pixel.data[0] + "," +
                    pixel.data[1] + "," +
                    pixel.data[2] + "," +
                    pixel.data[3] + ")";
                ctx_output.beginPath();
                ctx_output.arc(x + .5 + size, y + .5 + size, size, 0, Math.PI*2, true);
                ctx_output.closePath();
                ctx_output.fill();
            }
        }
    }
}

canvas_output.onmousemove = function(e) {
    draw_output(e.offsetX, e.offsetY);
}

canvas_output.onmouseout = function() {
    draw_output(-1000, -1000);
}
draw_output(-1000, -1000);