I'm trying to add some inset shadows to my svg, to make it look more like this
Instead of like this
I tried adding an inset shadow to every path (filter="url(#inset-shadow)"), using the filter pattern I got from this answer and have listed below, but all it ends up doing is kind of giving each path an outline. You can check the code at this fiddle to see what I'm talking about.
<filter id="inset-shadow">
<feComponentTransfer in="SourceAlpha" result="inset-selection">
<feFuncA type="discrete" tableValues="0 1 1 1 1 1" />
</feComponentTransfer>
<feComponentTransfer in="SourceGraphic" result="original-no-fill">
<feFuncA type="discrete" tableValues="0 0 1" />
</feComponentTransfer>
<feColorMatrix type="matrix" in="original-no-fill" result="new-source-alpha" values="0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 1 0" />
<feGaussianBlur in="new-source-alpha" result="blur" stdDeviation="5" />
<feGaussianBlur in="new-source-alpha" result="blur2" stdDeviation="10" />
<feGaussianBlur in="new-source-alpha" result="blur3" stdDeviation="15" />
<feMerge result="blur">
<feMergeNode in="blur" mode="normal" />
<feMergeNode in="blur2" mode="normal" />
<feMergeNode in="blur3" mode="normal" />
</feMerge>
<feComposite operator="in" in="inset-selection" in2="blur" result="inset-blur" />
<feComposite operator="over" in="original-no-fill" in2="inset-blur" />
</filter>
How can I add inset shadows to my shapes, to make my svg look more like the image at the top of this post?
The one you are using may have been failing because it was intended for transparent paths. I didn't spend much time working out what is wrong.
In any case, here's one I've created, that might be a bit easier to understand and tinker with.
<svg viewBox="0 0 200 200" width="400">
<defs>
<filter id="inset-shadow" x="-50%" y="-50%" width="200%" height="200%">
<!-- change this to desired inset blur colour -->
<feFlood x="0%" y="0%" width="100%" height="100%" flood-color="black" result="flood"/>
<!-- cut a hole out of the flood fill where out shape is -->
<feComposite operator="out" in="flood" in2="SourceAlpha" result="outside" />
<!-- stack blurs to get a better effect -->
<feGaussianBlur in="outside" result="blur" stdDeviation="5" />
<feGaussianBlur in="outside" result="blur2" stdDeviation="10" />
<feGaussianBlur in="outside" result="blur3" stdDeviation="15" />
<feMerge result="blur">
<feMergeNode in="blur" mode="normal" />
<feMergeNode in="blur2" mode="normal" />
<feMergeNode in="blur3" mode="normal" />
</feMerge>
<!-- clip the full blur against the shape to retain just the part inside our shape -->
<feComposite operator="in" in="blur" in2="SourceGraphic" result="inset-blur" />
<!-- blend with our original graphic to create the final result -->
<feBlend in="SourceGraphic" in2="inset-blur" mode="multiply"/>
</filter>
</defs>
<rect x="50" y="50" width="100" height="100" fill="linen" filter="url(#inset-shadow)"/>
</svg>
And here is a modified version of your fiddle with this filter applied.
You may want to tinker with the stdDeviation values to adjust the size of your inset blur.
Related
I have svg rectangle, and I need to add an inset-shadow with spread, how it works in figma.
rectangle with inner-shadow with spread
Currently, I make a rectangle with blur and x, y position, but I don't know how to add spread for my filter for svg
<defs>
<filter
id={`inset-shadow`}
x="-50%"
y="-50%"
width="200%"
height="200%"
>
<feComponentTransfer in="SourceAlpha">
<feFuncA type="table" tableValues="1 0" />
</feComponentTransfer>
<feGaussianBlur stdDeviation={blur} />
<feOffset
dx={x}
dy={y}
result="offsetblur"
/>
<feFlood flood-color={innerShadowColor} result="color" />
<feComposite in2="offsetblur" operator="in" />
<feComposite in2="SourceAlpha" operator="in" />
<feMerge>
<feMergeNode in="SourceGraphic" />
<feMergeNode />
</feMerge>
</filter>
<defs>
<rect
x={0}
y={0}
width={100}
height={100}
fill="rgba(0,0,0,0)"
stroke={'red'}
strokeWidth={10}
pointerEvents="none"
rx={10}
filter={`url(#inset-shadow)`}
/>
Adjust the spread by adding a feComponentTransfer to the alpha
<feComponentTransfer>
<feFuncA type="linear" slope="1.5"/>
</feComponentTransfer>
I wrote this tool to help people understand how to write filters that duplicate graphic tools shadow
https://codepen.io/mullany/pen/xxPOoX
Just need add
<feMorphology operator="dilate" radius={innerShadow.spread} />
<svg>
<defs>
<filter
id={`inset-shadow`}
x="-50%"
y="-50%"
width="200%"
height="200%"
>
<feComponentTransfer in="SourceAlpha">
<feFuncA type="table" tableValues="1 0" />
</feComponentTransfer>
<feGaussianBlur stdDeviation={0} />
<feMorphology operator="dilate" radius={10} />
<feOffset
dx={0}
dy={0}
result="offsetblur"
/>
<feFlood flood-color={'red'} result="color" />
<feComposite in2="offsetblur" operator="in" />
<feComposite in2="SourceAlpha" operator="in" />
<feMerge>
<feMergeNode in="SourceGraphic" />
<feMergeNode />
</feMerge>
</filter>
<defs>
<rect
x={0}
y={0}
width={100}
height={100}
fill="blue"
pointerEvents="none"
rx={10}
filter={`url(#inset-shadow)`}
/>
</svg>
Is it possible to transform a font with CSS to have rounded edges?
I'm talking about an effect similar to this smooth edges in Photoshop
So far I tried using a SVG filter, but it seems a bit complicated.
Is there a better way?
The code for the SVG filter used is this:
<svg viewbox="0 0 100% 100%">
<defs>
<filter id="smooth">
<feMorphology operator="dilate" radius="0" />
<feGaussianBlur stdDeviation="3" />
<feComponentTransfer>
<feFuncA type="table" tableValues="0 0 1 1"></feFuncA>
</feComponentTransfer>
<feComponentTransfer>
<feFuncA type="table" tableValues="0 0 1 1"></feFuncA>
</feComponentTransfer>
<feComponentTransfer out="rounded1">
<feFuncA type="table" tableValues="0 0 1 1"></feFuncA>
</feComponentTransfer>
<feComposite in2="rounded1" in="SourceGraphics" operator="in"/>
</filter>
</defs>
</svg>
and the explanations are here: https://dev.to/codingdudecom/css-smooth-font-edges-3pbb
One possible solution is using a goo filter like so. As an observation you need to know that for a different font and a different font-size you may need to change the values of the feColorMatrix and stdDeviation
div {
height: 200px;
padding:10px 60px;
font-size:200px;
font-family:Arial;
filter:url(#goo);
}
svg{position:absolute;}
<svg width="0" height="0">
<defs>
<filter id="goo">
<feGaussianBlur in="SourceGraphic" stdDeviation="7" />
<feColorMatrix mode="matrix" values="1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 35 -7" />
<feBlend in="SourceGraphic" />
</filter>
</defs>
</svg>
<div>
<span>A B</span>
</div>
Please read about The Goeey Effect
<svg style="display:none">
<defs>
<filter id="blue-glow-display-none">
<feMorphology in="SourceAlpha" operator="dilate" radius="2" />
<feGaussianBlur stdDeviation="1" result="dilated" />
<feFlood flood-color="#33ccff" />
<feComposite in2="dilated" operator="in" />
<feOffset dy="-1" />
<feMerge>
<feMergeNode />
<feMergeNode in="SourceGraphic" />
</feMerge>
</filter>
</defs>
</svg>
<svg style="position: absolute; left: -9999px;">
<defs>
<filter id="blue-glow-position-absolute">
<feMorphology in="SourceAlpha" operator="dilate" radius="2" />
<feGaussianBlur stdDeviation="1" result="dilated" />
<feFlood flood-color="#33ccff" />
<feComposite in2="dilated" operator="in" />
<feOffset dy="-1" />
<feMerge>
<feMergeNode />
<feMergeNode in="SourceGraphic" />
</feMerge>
</filter>
</defs>
</svg>
<img src="https://www.gravatar.com/avatar/6801bf30e40c9f7972987d67e2d5e4f2?s=48&d=identicon&r=PG" style="filter: url(#blue-glow-display-none)" />
<img src="https://www.gravatar.com/avatar/6801bf30e40c9f7972987d67e2d5e4f2?s=48&d=identicon&r=PG" style="filter: url(#blue-glow-position-absolute)" />
The contents of the two SVGs are identical (save for a different ID), the only thing different is that one is hidden with display:none while the other uses position:absolute to remove it from view.
display:none causes the filter to not get its colour, resulting in black. This also applies when the SVG is loaded from an external file with filter:url('/path/to/file.svg#blue-glow-external').
What's going on here, and how can I fix this issue?
So I've got this svg of a code symbol on my website and I want to add a long shadow to the svg. I've tried using filter: drop-shadow() but that only allows for one offset, I'm looking for the same feature as box-shadow where I can add multiple offsets to make a long shadow.
I'm using Sass for my styling and have made a function that makes long shadows for boxes and then is called with a mixin but unfortunately I can't find how to do the same with svg.
Anyone got any work arounds?
Not entirely sure what you mean by a long shadow - but I'm assuming that you're looking for an extrusion? You can do that by doing multiple offsets and in a SVG filter - and then referencing that filter from CSS.
.icon {
width: 50px;
height: 50px;
filter: url(#long-shadow);
}
<img class="icon" src="https://material.io/tools/icons/static/ic_icons_192px_light.svg">
<svg width="0px" height="0px">
<defs>
<filter id="long-shadow" x="0%" width="130%" y="0%" height="130%">
<feOffset dx="1" dy="1" result="layer1" in="SourceAlpha"/>
<feOffset dx="1" dy="1" result="layer2" />
<feOffset dx="1" dy="1" result="layer3" />
<feOffset dx="1" dy="1" result="layer4" />
<feOffset dx="1" dy="1" result="layer5" />
<feOffset dx="1" dy="1" result="layer6" />
<feOffset dx="1" dy="1" result="layer7" />
<feMerge>
<feMergeNode in="layer1"/>
<feMergeNode in="layer2"/>
<feMergeNode in="layer3"/>
<feMergeNode in="layer4"/>
<feMergeNode in="layer5"/>
<feMergeNode in="layer6"/>
<feMergeNode in="layer7"/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
</defs>
</svg>
I am trying to get an inset shadow only on 3 sides (top, left and right) using SVG filters. Please see the code below which adds inset shadow on all the four sides and see if you can help me modify it to get a shadow only on 3 sides. Thank you!
<svg>
<filter id="inset-shadow" x="-50%" y="-1" width="200%" height="205%">
<feComponentTransfer in=SourceAlpha>
<feFuncA type="table" tableValues="1 0 0 0 0 0 0" />
</feComponentTransfer>
<feGaussianBlur stdDeviation="5"/>
<feOffset dx="0" dy="0" result="offsetblur"/>
<feFlood flood-opacity="0.9" flood-color="rgb(20, 0, 0)" result="color"/>
<feComposite in2="offsetblur" operator="in"/>
<feComposite in2="SourceAlpha" operator="in"/>
<feMerge>
<feMergeNode in="SourceGraphic" />
<feMergeNode />
</feMerge>
</filter>
<filter id="inset-shadow1" x="-50%" y="0" width="200%" height="200%">
<feComponentTransfer in=SourceAlpha>
<feFuncA type="table" tableValues="1 0" />
</feComponentTransfer>
<feGaussianBlur stdDeviation="5"/>
<feOffset dx="0" dy="-1" result="offsetblur"/>
<feFlood flood-color="rgb(20, 0, 0)" result="color"/>
<feComposite in2="offsetblur" operator="in"/>
<feComposite in2="SourceAlpha" operator="in" />
<feMerge>
<feMergeNode in="SourceGraphic" />
<feMergeNode />
</feMerge>
</filter>
</svg>
Just adjust the filter region coordinates so that they line up with the left or top edges of the source graphic and adjust the width/height so that they're not clipping the right/bottom edge. Like so:
<svg width="800px" height="600px">
<defs>
<filter id="inset-shadow" x="0%" y="-100%" width="200%" height="205%">
<feComponentTransfer in=SourceAlpha>
<feFuncA type="table" tableValues="1 0 0 0 0 0 0" />
</feComponentTransfer>
<feGaussianBlur stdDeviation="5"/>
<feOffset dx="0" dy="0" result="offsetblur"/>
<feFlood flood-opacity="0.9" flood-color="rgb(20, 0, 0)" result="color"/>
<feComposite in2="offsetblur" operator="in"/>
<feComposite in2="SourceAlpha" operator="in"/>
<feMerge>
<feMergeNode in="SourceGraphic" />
<feMergeNode />
</feMerge>
</filter>
<filter id="inset-shadow1" x="-100%" y="0%" width="250%" height="200%">
<feComponentTransfer in=SourceAlpha>
<feFuncA type="table" tableValues="1 0" />
</feComponentTransfer>
<feGaussianBlur stdDeviation="5"/>
<feOffset dx="0" dy="-1" result="offsetblur"/>
<feFlood flood-color="rgb(20, 0, 0)" result="color"/>
<feComposite in2="offsetblur" operator="in"/>
<feComposite in2="SourceAlpha" operator="in" />
<feMerge>
<feMergeNode in="SourceGraphic" />
<feMergeNode />
</feMerge>
</filter>
</defs>
<rect filter="url(#inset-shadow)" fill="white" x="100" y="100" width="200" height="200"/>
<rect filter="url(#inset-shadow1)" fill="white" x="100" y="400" width="200" height="200"/>
</svg>