// set our SVGfilter's colorMatrix's values
document.getElementById('matrix').setAttribute('values', hueRotate(100));
var cssCtx = CSSFiltered.getContext('2d');
var svgCtx = SVGFiltered.getContext('2d');
var reqctx = requiredRes.getContext('2d');
cssCtx.fillStyle = svgCtx.fillStyle = reqctx.fillStyle = 'hsl(100, 50%, 50%)';
cssCtx.fillRect(0, 0, 100, 100);
svgCtx.fillRect(0, 0, 100, 100);
reqctx.fillRect(0, 0, 100, 100);
// CSSFunc
cssCtx.filter = "hue-rotate(100deg)";
// url func pointing to our SVG Filter
svgCtx.filter = "url(#hue-rotate)";
reqctx.fillStyle = 'hsl(200, 50%, 50%)';
cssCtx.fillRect(100, 0, 100, 100);
svgCtx.fillRect(100, 0, 100, 100);
reqctx.fillRect(100, 0, 100, 100);
var reqdata = reqctx.getImageData(150, 50, 1, 1).data;
var reqHSL = rgbToHsl(reqdata);
console.log('required result : ', 'rgba(' + reqdata.join() + '), hsl(' + reqHSL + ')');
var svgData = svgCtx.getImageData(150, 50, 1, 1).data;
var svgHSL = rgbToHsl(svgData);
console.log('SVGFiltered : ', 'rgba(' + svgData.join() + '), , hsl(' + svgHSL + ')');
// this one throws an security error in Firefox < 52
var cssData = cssCtx.getImageData(150, 50, 1, 1).data;
var cssHSL = rgbToHsl(cssData);
console.log('CSSFiltered : ', 'rgba(' + cssData.join() + '), hsl(' + cssHSL + ')');
// hueRotate will create a colorMatrix with the hue rotation applied to it
// taken from https://pixijs.github.io/docs/filters_colormatrix_ColorMatrixFilter.js.html
// and therefore from https://stackoverflow.com/questions/8507885/shift-hue-of-an-rgb-color/8510751#8510751
function hueRotate(rotation) {
rotation = (rotation || 0) / 180 * Math.PI;
var cosR = Math.cos(rotation),
sinR = Math.sin(rotation),
sqrt = Math.sqrt;
var w = 1 / 3,
sqrW = sqrt(w);
var a00 = cosR + (1.0 - cosR) * w;
var a01 = w * (1.0 - cosR) - sqrW * sinR;
var a02 = w * (1.0 - cosR) + sqrW * sinR;
var a10 = w * (1.0 - cosR) + sqrW * sinR;
var a11 = cosR + w * (1.0 - cosR);
var a12 = w * (1.0 - cosR) - sqrW * sinR;
var a20 = w * (1.0 - cosR) - sqrW * sinR;
var a21 = w * (1.0 - cosR) + sqrW * sinR;
var a22 = cosR + w * (1.0 - cosR);
var matrix = [
a00, a01, a02, 0, 0,
a10, a11, a12, 0, 0,
a20, a21, a22, 0, 0,
0, 0, 0, 1, 0,
];
return matrix.join(' ');
}
function rgbToHsl(arr) {
var r = arr[0] / 255,
g = arr[1] / 255,
b = arr[2] / 255;
var max = Math.max(r, g, b),
min = Math.min(r, g, b);
var h, s, l = (max + min) / 2;
if (max == min) {
h = s = 0;
} else {
var d = max - min;
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
switch (max) {
case r:
h = (g - b) / d + (g < b ? 6 : 0);
break;
case g:
h = (b - r) / d + 2;
break;
case b:
h = (r - g) / d + 4;
break;
}
h /= 6;
}
return [
Math.round(h * 360),
Math.round(s * 100),
Math.round(l * 100)
];
}
body{ margin-bottom: 100px}
<!-- this is our filter, we'll add the values by js -->
<svg height="0" width="0">
<filter id="hue-rotate">
<feColorMatrix in="SourceGraphic" id="matrix" type="matrix" color-interpolation-filters="sRGB" />
</filter>
</svg>
<p>CSS Filtered :
<br>
<canvas id="CSSFiltered" width="200" height="100"></canvas>
</p>
<p>SVG Filtered :
<br>
<canvas id="SVGFiltered" width="200" height="100"></canvas>
</p>
<p>Required Result :
<br>
<canvas id="requiredRes" width="200" height="100"></canvas>
</p>