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();
...