JSFiddle - React, Tailwind, and code Playground

by Dogbert

HTML

<script src="https://rawgit.com/betamax/getImageData/master/jquery.getimagedata.min.js"></script>
<canvas id="base"></canvas>
<div id="log" style="max-height: 40px; overflow-y: scroll; border: 1px solid gray;"></div>

JavaScript

// Output debugging information
function log(txt) {
    $('#log').prepend($('<p></p>').text(txt));
}

/**
 * Edit this function to change how you want to blend the pattern.
 *
 * The implementation here is a simple average. More blend modes can be found on Wikipedia:
 * https://en.wikipedia.org/wiki/Blend_modes
 */
function combine(a, b) {
    return ((a + b) * 0.5) | 0;
}

// Merge the pattern onto the base image
function addOverlay(ctx, ovlyCtx) {
    log('Adding the overlay');

    // Get the base image data
    var image_data = ctx.getImageData(0, 0, ctx.canvas.width, ctx.canvas.height);
    var image_data_array = image_data.data;

    // Get the pattern image data
    var overlay_data = ovlyCtx.getImageData(0, 0, ovlyCtx.canvas.width, ovlyCtx.canvas.height).data;
 
    // Loop over the pixels in the base image and merge the colors
    for (var i = 0, j = image_data_array.length; i < j; i+=4) {
        // Only merge when the base image pixel is nontransparent
        // Alternatively you could implement a border-checking algorithm depending on your needs
        if (image_data_array[i+3] > 0) {
            image_data_array[i+0] = combine(image_data_array[i+0], overlay_data[i+0]); // r
            image_data_array[i+1] = combine(image_data_array[i+1], overlay_data[i+1]); // g
            image_data_array[i+2] = combine(image_data_array[i+2], overlay_data[i+2]); // b
        }
    }
 
    // Write the image data back to the canvas
    var newCanvas = document.createElement('canvas');
    newCanvas.width = ctx.canvas.width;
    newCanvas.height = ctx.canvas.height;
    $(newCanvas).css('border', '1px solid black');
    var newContext = newCanvas.getContext('2d');
    newContext.putImageData(image_data, 0, 0);
    $(ctx.canvas).before(newCanvas);
}

// Tile the pattern image to the size of the base image
function setupOverlay(baseCtx, w, h) {
    $.getImageData({
        url: "http://i.stack.imgur.com/BooMu.png",
        success: function(image) {
           ...