SVG Path shadow only on outside of the form - 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>

Related

How to use an animated filter in an SVG mask?

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>

How to make this SVG pattern seamless?

I'm trying to make a SVG pattern seamless but with no luck
https://codepen.io/unlocomqx/pen/LYzbbNp
Code
<svg viewBox="0 0 100 100" width="300" height="300">
<defs>
<pattern id="grid2" width="10pt" height="10pt" patternUnits="userSpaceOnUse">
<path d="M 0 0 L 0 10 10 10 10 0 0 0" fill="#f7f6f4" stroke="#DDD" stroke-width="0.5"/>
</pattern>
</defs>
<rect x="0" y="0" width="100" height="100" fill="url(#grid2)"></rect>
</svg>
When I change the size to 5pt instead of 10pt, it works well
<svg viewBox="0 0 100 100" width="300" height="300">
<defs>
<pattern id="grid1" width="5pt" height="5pt" patternUnits="userSpaceOnUse">
<path d="M 0 0 L 0 10 10 10 10 0 0 0" fill="#f7f6f4" stroke="#DDD" stroke-width="0.5"/>
</pattern>
</defs>
<rect x="0" y="0" width="100" height="100" fill="url(#grid1)"></rect>
</svg>
How to fix it for the 10pt case?
You're running into the problem here that you can still only use SVG's built-in userSpaceOnUse or objectBoundingBox units for paths, so you'll have to use a rect, which does support more unit types (like pts).
Not seamless
<svg viewBox="0 0 100 100" width="300" height="300">
<defs>
<pattern id="grid2" width="10pt" height="10pt" patternUnits="userSpaceOnUse">
<rect x="0pt" y="0pt" width="10pt" height="10pt" fill="#f7f6f4" stroke="#DDD" stroke-width="0.5"/>
</pattern>
</defs>
<rect x="0" y="0" width="100" height="100" fill="url(#grid2)"></rect>
</svg>
Seamless
<svg viewBox="0 0 100 100" width="300" height="300">
<defs>
<pattern id="grid1" width="5pt" height="5pt" patternUnits="userSpaceOnUse">
<path d="M 0 0 L 0 10 10 10 10 0 0 0" fill="#f7f6f4" stroke="#DDD" stroke-width="0.5"/>
</pattern>
</defs>
<rect x="0" y="0" width="100" height="100" fill="url(#grid1)"></rect>
</svg>

How to use SVG-Uri in React-native or Expo?

I downloaded the expo-svg-uri module to use the Svg image.
But the image doesn't come out right.
Code I failed:
<View style={styles.container}>
<SvgUri
width="200"
height="200"
source={require("../../image/minigroup.svg")}
/>
</View>
Failed Image
Original Image
this is my svgfile
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="80" height="183" viewBox="0 0 80 183">
<defs>
<circle id="b" cx="35" cy="35" r="35"/>
<filter id="a" width="142.9%" height="142.9%" x="-21.4%" y="-21.4%" filterUnits="objectBoundingBox">
<feOffset in="SourceAlpha" result="shadowOffsetOuter1"/>
<feGaussianBlur in="shadowOffsetOuter1" result="shadowBlurOuter1" stdDeviation="5"/>
<feColorMatrix in="shadowBlurOuter1" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.12 0"/>
</filter>
<circle id="d" cx="35" cy="34" r="24"/>
<filter id="c" width="168.8%" height="168.8%" x="-28.1%" y="-28.1%" filterUnits="objectBoundingBox">
<feOffset dx="3" dy="3" in="SourceAlpha" result="shadowOffsetOuter1"/>
<feGaussianBlur in="shadowOffsetOuter1" result="shadowBlurOuter1" stdDeviation="5"/>
<feColorMatrix in="shadowBlurOuter1" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.12 0"/>
</filter>
<circle id="f" cx="35" cy="34" r="12"/>
<filter id="e" width="208.3%" height="208.3%" x="-45.8%" y="-45.8%" filterUnits="objectBoundingBox">
<feOffset dx="2" dy="2" in="SourceAlpha" result="shadowOffsetOuter1"/>
<feGaussianBlur in="shadowOffsetOuter1" result="shadowBlurOuter1" stdDeviation="4"/>
<feColorMatrix in="shadowBlurOuter1" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.12 0"/>
</filter>
</defs>
<g fill="none" fill-rule="evenodd">
<text fill="#646464" font-family="Bungee-Regular, Bungee" font-size="20" letter-spacing="-.375">
<tspan x="6.107" y="163">Point</tspan>
</text>
<text fill="#3D3D3D" font-family="Bungee-Regular, Bungee" font-size="20" letter-spacing="-.375">
<tspan x="20.282" y="140">Tap</tspan>
</text>
<g transform="translate(5 5)">
<rect width="70" height="81" y="28" fill="#FFD90D" rx="12"/>
<use fill="#000" filter="url(#a)" xlink:href="#b"/>
<use fill="#FFD90D" xlink:href="#b"/>
<use fill="#000" filter="url(#c)" xlink:href="#d"/>
<use fill="#FFD90D" xlink:href="#d"/>
<g>
<use fill="#000" filter="url(#e)" xlink:href="#f"/>
<use fill="#FFD90D" xlink:href="#f"/>
</g>
</g>
</g>
</svg>
I don't have a path value, I'm only drawing it all. Are you saying this is possible?
Please help us a lot. Thank you in advance.
First
Drag your svg file into this online tool SVGOMG
Switch to the Markup tab.
Copy d attribute of the path xml tag.
Second
Render your svg file directly using react-native-svg
react-native-svg is already installed and linked if you're using expo
Example that would render Home icon:
<Svg
width="20"
height="20"
viewBox="0 0 512 512" // Has to be the same of the original svg file
>
<Path
d="M208 448V320h96v128h97.6V256H464L256 64 48 256h62.4v192z"
fill="red"
/>
</Svg>
This 'd save you as well the cost of loading and reading file ...

Humongous height value for <filter> not preventing cutoff

I am trying to apply a <filter> on a <path> but I am having problems with things being clipped, not just the blur but also parts of original image, namely the markers.
So I tried increasing the default filter height (which is 120%) but it did not seem to help.
<svg style="height:400px;width:100%;background-color:LightCyan">
<defs>
<filter id="colorFilter" height="999%">
<feGaussianBlur in="SourceAlpha" stdDeviation="1" result="blur"></feGaussianBlur>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 3 0" result="lightenedBlur"></feColorMatrix>
<feMerge>
<feMergeNode in="lightenedBlur"></feMergeNode>
<feMergeNode in="SourceGraphic"></feMergeNode>
</feMerge>
</filter>
<marker id="arrow" viewBox="0 -5 10 10" refX="0" refY="0" markerWidth="8" markerHeight="8" orient="auto" style="fill: grey;">
<path d="M0,-5L10,0L0,5"></path>
</marker>
</defs>
<g transform="scale(2)">
<g transform="translate(-500,-230)">
<path stroke="grey" fill="none" marker-end="url(#arrow)" d="M555,274L657.4632873535149,274L657.4632873535149,271.03831481933645L759.92657470703,271.03831481933645"></path>
</g>
<g transform="translate(-500,-200)" filter="url(#colorFilter)">
<path stroke="grey" fill="none" marker-end="url(#arrow)" d="M555,274L657.4632873535149,274L657.4632873535149,271.03831481933645L759.92657470703,271.03831481933645"></path>
</g>
<g transform="translate(-500,-120)" filter="url(#colorFilter)">
<path stroke="grey" fill="none" marker-end="url(#arrow)" d="M555,274L657.6947631835931,274L657.6947631835931,222.58172607421926L760.3895263671862,222.58172607421926"></path>
</g>
</g>
</svg>
Now the <g> spans as much as is necessary to surround all its children, which means that for the top arrow the height isn't very much to begin with so I tried using absolute instead of relative values for the height but that does not help either:
<svg style="height:300px;width:100%;background-color:LightCyan">
<defs>
<filter id="colorFilter" height="1234">
<feGaussianBlur in="SourceAlpha" stdDeviation="1" result="blur"></feGaussianBlur>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 3 0" result="lightenedBlur"></feColorMatrix>
<feMerge>
<feMergeNode in="lightenedBlur"></feMergeNode>
<feMergeNode in="SourceGraphic"></feMergeNode>
</feMerge>
</filter>
<marker id="arrow" viewBox="0 -5 10 10" refX="0" refY="0" markerWidth="8" markerHeight="8" orient="auto" style="fill: grey;">
<path d="M0,-5L10,0L0,5"></path>
</marker>
</defs>
<g transform="scale(2)">
<g transform="translate(-500,-230)" filter="url(#colorFilter)">
<path stroke="grey" fill="none" marker-end="url(#arrow)" d="M555,274L657.4632873535149,274L657.4632873535149,271.03831481933645L759.92657470703,271.03831481933645"></path>
</g>
<g transform="translate(-500,-150)" filter="url(#colorFilter)">
<path stroke="grey" fill="none" marker-end="url(#arrow)" d="M555,274L657.6947631835931,274L657.6947631835931,222.58172607421926L760.3895263671862,222.58172607421926"></path>
</g>
</g>
</svg>
Any idea what might cause this clipping and what can be done about it? Why do height attribute values above a certain point have not effect here?
(Reproduced in Chrome, Firefox and Edge – does not look like a browser bug.)
You have to move the upper border of the filter effect region as well. Default is y=-10%.
<svg style="height:400px;width:100%;background-color:LightCyan">
<defs>
<filter id="colorFilter" y="-200%" height="500%">
<feGaussianBlur in="SourceAlpha" stdDeviation="1" result="blur"></feGaussianBlur>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 3 0" result="lightenedBlur"></feColorMatrix>
<feMerge>
<feMergeNode in="lightenedBlur"></feMergeNode>
<feMergeNode in="SourceGraphic"></feMergeNode>
</feMerge>
</filter>
<marker id="arrow" viewBox="0 -5 10 10" refX="0" refY="0" markerWidth="8" markerHeight="8" orient="auto" style="fill: grey;">
<path d="M0,-5L10,0L0,5"></path>
</marker>
</defs>
<g transform="scale(2)">
<g transform="translate(-500,-230)">
<path stroke="grey" fill="none" marker-end="url(#arrow)" d="M555,274L657.4632873535149,274L657.4632873535149,271.03831481933645L759.92657470703,271.03831481933645"></path>
</g>
<g transform="translate(-500,-200)" filter="url(#colorFilter)">
<path stroke="grey" fill="none" marker-end="url(#arrow)" d="M555,274L657.4632873535149,274L657.4632873535149,271.03831481933645L759.92657470703,271.03831481933645"></path>
</g>
<g transform="translate(-500,-120)" filter="url(#colorFilter)">
<path stroke="grey" fill="none" marker-end="url(#arrow)" d="M555,274L657.6947631835931,274L657.6947631835931,222.58172607421926L760.3895263671862,222.58172607421926"></path>
</g>
</g>
</svg>
As an aside, using absolute values only works if you set filterUnits="userSpaceOnUse". The same note on the use of y values applies.

Cannot display more than one svg on page

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>

Resources