JSFiddle - React, Tailwind, and code Playground

HTML

<img id="img" alt=""...

CSS

.row {
    text-align: center;
}
.col {
    display: inline-block;
}
input[type=range] {
    width: 300px;
}
strong {
    display: block;
}

.controls {
    text-align: center;
}

JavaScript

var invertCache,
    tmpCtx = document.createElement('canvas').getContext('2d');
function fast(img, ctx, w, h, val) {
    if (!invertCache) {
        // inverse source
        invertCache = document.createElement('canvas');
        invertCache.width = w;
        invertCache.height = h;
        var invertCacheCtx = invertCache.getContext('2d');
        invertCacheCtx.save();
        invertCacheCtx.fillStyle = "#ffffff";
        invertCacheCtx.fillRect(0, 0, w, h);
        invertCacheCtx.globalCompositeOperation = "difference";
        invertCacheCtx.drawImage(img, 0, 0);
        invertCacheCtx.restore();
    }
    
    // add value
    var minVal = Math.abs(val),
        targetCtx = val >= 0 ? ctx : tmpCtx;
    if (val < 0) {
        targetCtx.canvas.width = w;
        targetCtx.canvas.height = h;
    }
    targetCtx.save();
    targetCtx.fillStyle = "rgb(" + minVal + "," + minVal + "," + minVal + " )";
    targetCtx.fillRect(0, 0, w, h);
    targetCtx.globalCompositeOperation = "lighter";
    targetCtx.drawImage(val >= 0 ? img : invertCache, 0, 0);
    targetCtx.restore();
    
    if (val < 0) {
        // invert result
        ctx.save();
        ctx.fillStyle = "#ffffff";
        ctx.fillRect(0, 0, w, h);
        ctx.globalCompositeOperation = "difference";
        ctx.drawImage(tmpCtx.canvas, 0, 0);
        ctx.restore();
    }
}

function slow(img, ctx, w, h, val) {
    // reset canvas
    ctx.drawImage(img, 0, 0);
    var imageData = ctx.getImageData(0, 0, w, h),
        d = imageData.data;
    for(var i = 0, l = d.length;i<l;i+=4) {
        d[i] += val; // R component
        d[i+1] += val; // G component
        d[i+2] += val; // B component
    }
    ctx.putImageData(imageData, 0, 0);
}

function update () {
    value = parseInt(this.value);
    // render fast
    var start = Date.now();
    fast(img, fastCtx, width, height, value);
    var end = Date.now();
    fastPlaceholder.innerText = end - start;
    // render slow
    start = Date.now();
   ...