Search code examples
javascriptjqueryinternet-explorerfiltersvg-filters

How to combine both grayscale and invert effect with an SVG filter in IE?


I would like to use an SVG filter to grayscale and/or invert an image in IE10+ browsers, but am struggling to combine the two effects. Do I need to combine the operations within one value matrix? Or should I be applying two different SVG filters and toggling them on and off separately?

Here is the filter I am using for grayscale, invert just uses a different matrix:

opts.svgContent = '<svg xmlns="http://www.w3.org/2000/svg" id="svgroot_' + opts.idHash + '" class="'+$elm[0].className+' " viewBox="0 0 ' + opts.svgWidth + ' ' + opts.svgHeight + '" width="' + opts.svgWidth + '" height="' + opts.svgHeight + '">';
opts.svgContent += '<defs>';
opts.svgContent += '<filter id="filtersPicture_' + opts.idHash + '" >';
opts.svgContent += '<feComposite result="inputTo_' + opts.idHash + '" in="SourceGraphic" in2="SourceGraphic" operator="arithmetic" k1="0" k2="1" k3="0" k4="0" />';
opts.svgContent += '<feColorMatrix in="SourceGraphic" type="matrix" values="0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0"/>';
opts.svgContent += '</filter>';
opts.svgContent += '</defs>';
opts.svgContent += '<image filter="url(\'#filtersPicture_' + opts.idHash + '\')" x="0" y="0" width="' + opts.svgWidth + '" height="' + opts.svgHeight + '" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="' + opts.svgSource + '" />';
opts.svgContent += '</svg>';

Note this is being adapted from the InvertImages Plugin.


Solution

  • You could add the inversion filter to a <g> wrapper element and then use JavaScript to add/remove the filter attribute from your image and g elements.

    For an inversion filter, just replace your feColorMatrix line with this:

    opts.svgContent += '<feColorMatrix type="matrix" values="-1 0 0 0 0  0 -1 0 0 0  0 0 -1 0 0   0 0 0 1 0"/>';
    

    (Also your first feComposite doesn't do anything, you should remove it.)