Photoshop blend filters for Canvas - https://jsfiddle.net/o1trjvo7/22/
// Working example can be found here https://jsfiddle.net/o1trjvo7/22/
var targetCanvas = document.getElementById('target-canvas');
var targetContext = targetCanvas.getContext('2d');
var targetImage = document.getElementById('target-image');
targetContext.drawImage(targetImage, 0, 0);
var tData = targetContext.getImageData(0, 0, targetCanvas.width, targetCanvas.height);
var target = tData.data;
var blendCanvas = document.getElementById('blend-canvas');
var blendContext = blendCanvas.getContext('2d');
var blendImage = document.getElementById('blend-image');
blendContext.drawImage(blendImage, 0, 0);
var bData = blendContext.getImageData(0, 0, blendCanvas.width, blendCanvas.height);
var blend = bData.data;
// change this to one of the following
// darken, multiply, colorburn, linearburn, lighten, screen, colordodge,
// lineardodge, overlay, softlight, hardlight, linearlight, pinlight, difference, exclusion
var mode = 'multiply';
for(var i=0; i<target.length; i+=4){
var targetR = target[i] / 255;
var targetG = target[i+1] / 255;
var targetB = target[i+2] / 255;
var blendR = blend[i] / 255;
var blendG = blend[i+1] / 255;
var blendB = blend[i+2] / 255;
// Darken
if(mode == 'darken'){
target[i] = Math.min(targetR, blendR) * 255;
target[i+1] = Math.min(targetG, blendG) * 255;
target[i+2] = Math.min(targetB, blendB) * 255;
}
// Multiply
if(mode == 'multiply'){
target[i] = (targetR * blendR) * 255;
target[i + 1] = (targetG * blendG) * 255;
target[i + 2] = (targetB * blendB) * 255;
}
// Color Burn
if(mode == 'colorburn'){
target[i] = (1 - (1 - targetR) / blendR) * 255;
target[i+1] = (1 - (1 - targetG) / blendG) * 255;
target[i+2] = (1 - (1 - targetB) / blendB) * 255;
}
// Linear Burn
if(mode == 'linearburn'){
target[i] = (blendR + targetR - 1) * 255;
target[i+1] = (blendG + targetG - 1) * 255;
target[i+2] = (blendB + targetB - 1) * 255;
}
// Lighten
if(mode == 'lighten'){
target[i] = Math.max(targetR, blendR) * 255;
target[i+1] = Math.max(targetG, blendG) * 255;
target[i+2] = Math.max(targetB, blendB) * 255;
}
// Screen
if(mode == 'screen'){
target[i] = (1 - (1 - targetR) * (1 - blendR)) * 255;
target[i+1] = (1 - (1 - targetG) * (1 - blendG)) * 255;
target[i+2] = (1 - (1 - targetB) * (1 - blendB)) * 255;
}
// Color Dodge
if(mode == 'colordodge'){
target[i] = targetR / (1-blendR) * 255;
target[i + 1] = targetG / (1-blendG) * 255;
target[i + 2] = targetB / (1-blendB) * 255;
}
// Linear Dodge
if(mode == 'lineardodge'){
target[i] = (targetR + blendR) * 255;
target[i + 1] = (targetG + blendG) * 255;
target[i + 2] = (targetB + blendB) * 255;
}
// Overlay
if(mode == 'overlay'){
target[i] = ((targetR > 0.5) * (1 - (1 - 2 * (targetR - 0.5)) * (1 - blendR)) + (targetR <= 0.5) * ((2 * targetR) * blendR)) * 255;
target[i + 1] = ((targetG > 0.5) * (1 - (1 - 2 * (targetG - 0.5)) * (1 - blendG)) + (targetG <= 0.5) * ((2 * targetG) * blendG)) * 255;
target[i + 2] = ((targetB > 0.5) * (1 - (1 - 2 * (targetB - 0.5)) * (1 - blendB)) + (targetB <= 0.5) * ((2 * targetB) * blendB)) * 255;
}
// Soft Light
if(mode == 'softlight'){
target[i] = ((blendR > 0.5) * (1 - (1 - targetR) * (1 - (blendR - 0.5))) + (blendR <= 0.5) * (targetR * (blendR + 0.5))) * 255;
target[i + 1] = ((blendG > 0.5) * (1 - (1 - targetG) * (1 - (blendG - 0.5))) + (blendG <= 0.5) * (targetG * (blendG + 0.5))) * 255;
target[i + 2] = ((blendB > 0.5) * (1 - (1 - targetB) * (1 - (blendB - 0.5))) + (blendB <= 0.5) * (targetB * (blendB + 0.5))) * 255;
}
// Hard Light
if(mode == 'hardlight'){
target[i] = ((blendR > 0.5) * (1 - (1 - targetR) * (1 - 2 * (blendR - 0.5))) + (blendR <= 0.5) * (targetR * (2 * blendR))) * 255;
target[i+1] = ((blendG > 0.5) * (1 - (1 - targetG) * (1 - 2 * (blendG - 0.5))) + (blendG <= 0.5) * (targetG * (2 * blendG))) * 255;
target[i+2] = ((blendB > 0.5) * (1 - (1 - targetB) * (1 - 2 * (blendB - 0.5))) + (blendB <= 0.5) * (targetB * (2 * blendB))) * 255;
}
// Linear Light
if(mode == 'linearlight'){
target[i] = ((blendR > 0.5) * (targetR + 2*(blendR - 0.5)) + (blendR <= 0.5) * (targetR + 2 * blendR - 1)) * 255;
target[i+1] = ((blendG > 0.5) * (targetG + 2*(blendG - 0.5)) + (blendG <= 0.5) * (targetG + 2 * blendG - 1)) * 255;
target[i+2] = ((blendB > 0.5) * (targetB + 2*(blendB - 0.5)) + (blendB <= 0.5) * (targetB + 2 * blendB - 1)) * 255;
}
// Pin Light
if(mode == 'pinlight'){
target[i] = ((blendR > 0.5) * (Math.max(targetR, 2*(blendR-0.5))) + (blendR <= 0.5) * (Math.min(targetR, 2 * blendR))) * 255;
target[i+1] = ((blendG > 0.5) * (Math.max(targetG, 2*(blendG-0.5))) + (blendG <= 0.5) * (Math.min(targetG, 2 * blendG))) * 255;
target[i+2] = ((blendB > 0.5) * (Math.max(targetB, 2*(blendB-0.5))) + (blendB <= 0.5) * (Math.min(targetB, 2 * blendB))) * 255;
}
// Difference
if(mode == 'difference'){
target[i] = (targetR > blendR ? targetR - blendR : blendR - targetR) * 255;
target[i+1] = (targetG > blendG ? targetG - blendG : blendG - targetG) * 255;
target[i+2] = (targetB > blendB ? targetB - blendB : blendB - targetB) * 255;
}
// Exclusion
if(mode == 'exclusion'){
target[i] = (0.5 - 2 * (targetR - 0.5) * (blendR - 0.5)) * 255;
target[i+1] = (0.5 - 2 * (targetG - 0.5) * (blendG - 0.5)) * 255;
target[i+2] = (0.5 - 2 * (targetB - 0.5) * (blendB - 0.5)) * 255;
}
}
targetContext.putImageData(tData, 0, 0);