I tried without success to use an animated filter noise on a mask to mask an element. The mask itself works but I am unable to get the animation working in the mask, even though the animation itself works.
I've tried all possible combination of the feColorMatrix (single channel, only alpha, various combinations) and both luminance and alpha types for the mask, yet nothing gives.
Any help would be greatly appreciated!
<svg width="200" height="200" viewBox="0 0 200 200"
xmlns="http://www.w3.org/2000/svg">
<defs>
<filter id="noise" x="0" y="0" width="100%" height="100%">
<feTurbulence type="fractalNoise" baseFrequency="0.01" seed="12345" />
<feColorMatrix type="hueRotate" values="0">
<animate attributeName="values" from="0" to="360" dur="5s" repeatCount="indefinite" />
</feColorMatrix>
<feColorMatrix type="matrix" values="0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 1 0 0 0 0 " />
</filter>
<mask id="Mask">
<rect x="0" y="0" width="100%" height="100%" filter="url(#noise)" />
</mask>
</defs>
<rect x="0" y="0" width="200" height="200" fill="green" />
<rect x="0" y="0" width="200" height="200" fill="red" mask="url(#Mask)" />
</svg>
EDIT:
It almost works, thanks to Michael. This is the updated code, essentially I am trying to merge two images, bottom one is a full image and the top image has an alpha and is transparent. It works but the noise is still visible on top of the image, even though the mask itself works (though it's hard to see because of the visible noise).
<svg width="960" height="1200" viewBox="0 0 960 1200"
xmlns="http://www.w3.org/2000/svg">
<defs>
<filter id="noise" x="0" y="0" width="100%" height="100%">
<feTurbulence type="fractalNoise" baseFrequency="0.005" seed="1" />
<feColorMatrix type="hueRotate" values="0">
<animate attributeName="values" from="0" to="360" dur="5s" repeatCount="indefinite" />
</feColorMatrix>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0" result="opacity-mask"/>
<feComposite operator ="in" in2="opacity-mask"/>
<feComposite operator="over" in2="SourceGraphic"/>
</filter>
<filter id="dropshadow">
<feGaussianBlur in="SourceAlpha" stdDeviation="20" />
<feOffset dx="5" dy="5" result="offsetblur" />
<feFlood flood-color="#000" flood-opacity="1" result="offsetColor"/>
<feComposite in="offsetColor" in2="offsetblur" operator="in" result="offsetblur"/>
<feComposite operator="over" in2="SourceGraphic"/>
</filter>
</defs>
<image href="https://martinhoura.net/svg/img_bottom.jpg" width="100%" x="0%" y="0" />
<g filter="url(#noise)">
<image href="https://martinhoura.net/svg/img_top.png" width="100%" x="0" y="0" filter="url(#dropshadow)" />
</g>
</svg>
Animated filters can have problems in Chrome and Safari when they're combined with patterns, masks and clips. You can fix this by doing the mask within the filter by using feComposite/in.
<svg width="200" height="200" viewBox="0 0 200 200"
xmlns="http://www.w3.org/2000/svg">
<defs>
<filter id="noise" x="0" y="0" width="100%" height="100%">
<feTurbulence type="fractalNoise" baseFrequency="0.01" seed="12345" />
<feColorMatrix type="hueRotate" values="0">
<animate attributeName="values" from="0" to="360" dur="5s" repeatCount="indefinite" />
</feColorMatrix>
<feColorMatrix type="matrix" values="0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 1 0 0 0 0" result="opacity-mask"/>
<feFlood flood-color="green"/>
<feComposite operator ="in" in2="opacity-mask"/>
<feComposite operator="over" in2="SourceGraphic"/>
</filter>
</defs>
<rect x="0" y="0" width="200" height="200" fill="red" filter="url(#noise)" />
</svg>
Update:
Thank you for posting the relevant code because the issues are different here.
There are two problems with your implementation. The first is that you're using the SourceGraphic as the mask on the Turbulence in your feComposite/in - so the turbulence is showing up, not the SourceGraphic - you need to change that 'in2' to 'in'.
But the bigger issue is that you're overlaying a variably-transparent version of the original image on top of the fully-opaque original image. The result of this is simply the original image. You need to make your underlying image semi-opaque if you want any effect to show up. Here's an exaggerated example of what I mean.
<svg width="960" height="1200" viewBox="0 0 960 1200"
xmlns="http://www.w3.org/2000/svg">
<defs>
<filter id="noise" x="0" y="0" width="100%" height="100%">
<feTurbulence type="fractalNoise" baseFrequency="0.005" seed="1" />
<feColorMatrix type="hueRotate" values="0">
<animate attributeName="values" from="0" to="360" dur="5s" repeatCount="indefinite" />
</feColorMatrix>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0" result="opacity-mask"/>
<feComposite operator="in" in="SourceGraphic"/>
</filter>
<filter id="half-opacity">
<feColorMatrix type="matrix" values="1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 0.25 0"/>
</filter>
</defs>
<image filter="url(#half-opacity") href="https://martinhoura.net/svg/img_bottom.jpg" width="100%" x="0%" y="0" />
<g filter="url(#noise)">
<image href="https://martinhoura.net/svg/img_top.png" width="100%" x="0" y="0" />
</g>
</svg>
I have the following svg with a filter that works in Chrome but on ios only part of it works. Not sure if I'm doing something wrong or if ios doesn't fully support it.
<svg height="80" width="500" xmlns="http://www.w3.org/2000/svg">
<defs>
<circle cx="3" cy="3" r="2" id="circle" fill="#FFFFFF"></circle>
<filter height="100%" id="filter">
<feMorphology in="SourceAlpha" operator="dilate" radius="2.5"
result="MORPH1"></feMorphology>
<feColorMatrix in="MORPH1" result="GREYED" type="matrix"
values="0.8 0 0 0 0 0 0.8 0 0 0 0 0 0.8 0 0 0 0 0 0.5 0">
</feColorMatrix>
<feMorphology in="SourceAlpha" operator="dilate" radius="1.5"
result="MORPH2"></feMorphology>
<feColorMatrix in="MORPH2" result="WHITENED" type="matrix"
values="-1 0 0 1 0, 0 -1 0 1 0, 0 0 -1 1 0, 0 0 0 0.8 0">
</feColorMatrix>
<feImage height="2" width="2" xlink:href="#circle">
</feImage>
<feTile result="3dot"></feTile>
<feComposite in="3dot" in2="SourceGraphic" operator="in"
result="comp"></feComposite>
<feMerge>
<feMergeNode in="GREYED"></feMergeNode>
<feMergeNode in="WHITENED"></feMergeNode>
<feMergeNode in="SourceGraphic"></feMergeNode>
<feMergeNode in="comp"></feMergeNode>
</feMerge>
</filter>
</defs>
<text text-anchor="start" alignment-baseline="hanging" font-size="48"
x="20" y="20" fill="#803cac" stroke="#000000" stroke-width="1"
filter="url(#filter)">TEXT HERE</text>
</svg>
The result should look like
but on ios the dots are not displaying so everything apart from this part works
<feImage height="2" width="2" xlink:href="#circle">
</feImage>
<feTile result="3dot"></feTile>
<feComposite in="3dot" in2="SourceGraphic" operator="in"
result="comp"></feComposite>
This is a straight up bug in iOS/Safari (didn't test regular safari). The workaround is to "pre-tile" the fill using a filled shape. (Note Firefox doesn't support object references in feImage - so you'd need to use an inline data:uri for cross browser compat)
<svg height="80" width="500" xmlns="http://www.w3.org/2000/svg">
<defs>
<pattern id="circle-fill" width="2" height="2" patternUnits="userSpaceOnUse">
<circle cx="3" cy="3" r="2" id="circle" fill="white"/>
</pattern>
<rect x="0" y="0" id="filled-rect" width="100%" height="100%" fill="url(#circle-fill)"/>
<filter height="100%" id="filter">
<feMorphology in="SourceAlpha" operator="dilate" radius="2.5"
result="MORPH1"/>
<feColorMatrix in="MORPH1" result="GREYED" type="matrix"
values="0.8 0 0 0 0 0 0.8 0 0 0 0 0 0.8 0 0 0 0 0 0.5 0"/>
<feMorphology in="SourceAlpha" operator="dilate" radius="1.5"
result="MORPH2"/>
<feColorMatrix in="MORPH2" result="WHITENED" type="matrix"
values="-1 0 0 1 0 0 -1 0 1 0 0 0 -1 1 0, 0 0 0 0.8 0"/>
<feImage height="80" width="500" xlink:href="#filled-rect"/>
<feComposite in="3dot" in2="SourceGraphic" operator="in"
result="comp"/>
<feMerge>
<feMergeNode in="GREYED"/>
<feMergeNode in="WHITENED"/>
<feMergeNode in="SourceGraphic"/>
<feMergeNode in="comp"/>
</feMerge>
</filter>
</defs>
<text text-anchor="start" alignment-baseline="hanging" font-size="48"
x="20" y="20" fill="#803cac" stroke="#000000" stroke-width="1"
filter="url(#filter)">TEXT HERE</text>
</svg>
Not sure if I'm misunderstanding something fundamental about svgs, but when I try and add more than one svg on the page only the first one renders. The below svgs were exported from Sketch (I'm working on removing the fluff). The svg is in the dom (I can see it in the chrome inspector) but nothing renders on screen for the second svg. If I swap the order then again only the first one displays.
<svg width="18px" height="19px" viewBox="0 0 18 19" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 3.8.3 (29802) - http://www.bohemiancoding.com/sketch -->
<title>LinkedIn</title>
<desc>Created with Sketch.</desc>
<defs>
<path d="M404,1613.54534 L404,1620.20005 L400.142017,1620.20005 L400.142017,1613.99103 C400.142017,1612.43128 399.584002,1611.3668 398.18754,1611.3668 C397.121518,1611.3668 396.487128,1612.08418 396.208036,1612.77812 C396.106259,1613.0262 396.080062,1613.3715 396.080062,1613.71876 L396.080062,1620.20005 L392.220782,1620.20005 C392.220782,1620.20005 392.272758,1609.68401 392.220782,1608.59447 L396.079685,1608.59447 L396.079685,1610.23951 C396.07186,1610.25182 396.06169,1610.26508 396.054325,1610.27701 L396.079685,1610.27701 L396.079685,1610.23951 C396.592378,1609.44986 397.507994,1608.32182 399.557427,1608.32182 C402.096537,1608.32178 404,1609.98055 404,1613.54534 L404,1613.54534 Z M388.18381,1603 C386.863556,1603 386,1603.86598 386,1605.00478 C386,1606.11876 386.838572,1607.01102 388.132587,1607.01102 L388.158366,1607.01102 C389.504191,1607.01102 390.341172,1606.11893 390.341172,1605.00478 C390.315812,1603.86598 389.504191,1603 388.18381,1603 L388.18381,1603 Z M386.229207,1620.20005 L390.087023,1620.20005 L390.087023,1608.59447 L386.229207,1608.59447 L386.229207,1620.20005 L386.229207,1620.20005 Z" id="path-1"></path>
<filter x="-50%" y="-50%" width="200%" height="200%" filterUnits="objectBoundingBox" id="filter-2">
<feOffset dx="0" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0.239215686 0 0 0 0 0.490196078 0 0 0 1 0" type="matrix" in="shadowOffsetOuter1"></feColorMatrix>
</filter>
</defs>
<g id="1.-Homepage" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="1440/1a.-Homepage" transform="translate(-386.000000, -1603.000000)">
<g id="LinkedIn">
<use fill="black" fill-opacity="1" filter="url(#filter-2)" xlink:href="#path-1"></use>
<use fill="#FFFFFF" fill-rule="evenodd" xlink:href="#path-1"></use>
<use fill="black" fill-opacity="1" xlink:href="#path-1"></use>
</g>
</g>
</g>
</svg>
<svg width="10px" height="19px" viewBox="0 0 10 19" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 3.8.3 (29802) - http://www.bohemiancoding.com/sketch -->
<title>Shape</title>
<desc>Created with Sketch.</desc>
<defs>
<path d="M323.219245,1604.00369 L320.921439,1604 C318.339932,1604 316.671649,1605.7116 316.671649,1608.36076 L316.671649,1610.37137 L314.361308,1610.37137 C314.161667,1610.37137 314,1610.53322 314,1610.73286 L314,1613.64599 C314,1613.84563 314.161851,1614.0073 314.361308,1614.0073 L316.671649,1614.0073 L316.671649,1621.35807 C316.671649,1621.55771 316.833316,1621.71938 317.032957,1621.71938 L320.047295,1621.71938 C320.246936,1621.71938 320.408603,1621.55753 320.408603,1621.35807 L320.408603,1614.0073 L323.109931,1614.0073 C323.309572,1614.0073 323.471239,1613.84563 323.471239,1613.64599 L323.472345,1610.73286 C323.472345,1610.637 323.434186,1610.5452 323.366533,1610.47736 C323.29888,1610.40952 323.20671,1610.37137 323.110853,1610.37137 L320.408603,1610.37137 L320.408603,1608.66695 C320.408603,1607.84774 320.60382,1607.43187 321.670968,1607.43187 L323.218877,1607.43132 C323.418333,1607.43132 323.58,1607.26947 323.58,1607.07001 L323.58,1604.36499 C323.58,1604.16572 323.418518,1604.00406 323.219245,1604.00369 L323.219245,1604.00369 Z" id="path-1"></path>
<filter x="-50%" y="-50%" width="200%" height="200%" filterUnits="objectBoundingBox" id="filter-2">
<feOffset dx="0" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0.239215686 0 0 0 0 0.490196078 0 0 0 1 0" type="matrix" in="shadowOffsetOuter1"></feColorMatrix>
</filter>
</defs>
<g id="1.-Homepage" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="1440/1a.-Homepage" transform="translate(-314.000000, -1604.000000)">
<g id="Shape">
<use fill="black" fill-opacity="1" filter="url(#filter-2)" xlink:href="#path-1"></use>
<use fill="#FFFFFF" fill-rule="evenodd" xlink:href="#path-1"></use>
<use fill="black" fill-opacity="1" xlink:href="#path-1"></use>
</g>
</g>
</g>
</svg>
I have a simple closed svg path
<path d="M10 10 H 90 V 90 H 10 L 10 10" fill="none" stroke-width="2px" stroke="black" />
Is it possible to get a shadow effect only on the outside border?
Not like that:
But like that:
The inner part should remain transparent.
As #Robert Longson said using a mask is the solution:
<svg>
<defs>
<filter id="glow" x="-20%" y="-20%" width="140%" height="140%">
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 1 0"></feColorMatrix>
<feGaussianBlur stdDeviation="4" result="coloredBlur"></feGaussianBlur>
<feMerge>
<feMergeNode in="coloredBlur"></feMergeNode>
<feMergeNode in="SourceGraphic"></feMergeNode>
</feMerge>
</filter>
</defs>
<defs>
<mask id="myMask">
<rect x="0" y="0" width="100" height="100" fill="white" />
<rect x="11" y="11" width="78" height="78" fill="black" />
</mask>
</defs>
</svg>
<svg width="100px" height="100px" version="1.1" xmlns="http://www.w3.org/2000/svg">
<rect x="0" y="0" width="100" height="100" fill="yellow" />
<path d="M10 10 H 90 V 90 H 10 L 10 10" stroke-width="2px" stroke="black" filter="url(#glow)" mask="url(#myMask)" fill="none" />
</svg>
Here's the source:
<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg">
<g>
<defs>
<filter id="f1" x="0" y="0" width="200%" height="200%">
<feOffset result="offOut" in="SourceGraphic" dx="0" dy="0" />
<feColorMatrix result="matrixOut" in="offOut" type="matrix"
values="0.2 0 0 0 0 0 0.2 0 0 0 0 0 0.2 0 0 0 0 0 1 0" />
<feGaussianBlur result="blurOut" in="matrixOut" stdDeviation="10" />
<feBlend in="SourceGraphic" in2="blurOut" mode="normal" />
</filter>
</defs>
<path fill="#E0E0E0" stroke="#FFFFFF" stroke-width="5" d="M 50 50 l 100 0 l -50 86.6 z" filter="url(#f1)"/>
</g>
</svg>
And here's what it looks like rendered by Firefox: Chrome is similar.
Why is the drop shadow asymmetrical? I was hoping to make it look as though the illumination is from directly above the image, so the shadow should be symmetrical. It should end up looking something like the following raster image:
(I'm sorry the colours of the interiors don't match, but I'll fix that later.)
Is this more like what you want?
<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg">
<g>
<defs>
<filter id="f1" x="-1" y="-1" width="300%" height="300%">
<feOffset result="offOut" in="SourceGraphic" dx="0" dy="10" />
<feColorMatrix result="matrixOut" in="offOut" type="matrix"
values="0.2 0 0 0 0 0 0.2 0 0 0 0 0 0.2 0 0 0 0 0 1 0" />
<feGaussianBlur result="blurOut" in="matrixOut" stdDeviation="10" />
<feBlend in="SourceGraphic" in2="blurOut" mode="normal" />
</filter>
</defs>
<path fill="#E0E0E0" stroke="#FFFFFF" stroke-width="5" d="M 50 50 l 100 0 l -50 86.6 z" filter="url(#f1)"/>
</g>
</svg>
Edit: Explanation:
I made the filter effect region larger (using width/height on <filter>) so that it is larger than the bounding box of the shape (300% its width). Of course it has to be repositioned (using x/y) so that the shape sits in the center of the effect region. I also moved the shadow a little downwards using the y attribute on feOffset.
Side note: As Erik Dahlström mentioned in the comments, using 3 instead of 300% for width and height is equivalent in this case because filterUnits is implicitly set to objectBoundingBox. The same is true for -1 and -100% on x and y. I mixed both notations.