How to Make an Inset Drop Shadow in Svg

How to make an inset drop shadow in SVG

If you had a solid fill, you could just add

<feComposite operator="in" in2="SourceGraphic"/> 

to the end of your filter and it would clip the blur to the shape of the SourceGraphic. Since your shape is transparent, you'll have to do a little more work. What I'd suggest is using a semi-transparent fill on the original graphic in order to get the right selection for compositing and using an feFuncA to zero out the fill for the final operation. This turns out to be surprisingly complicated. But here is a solution that will work for any solid-stroke shape

<filter id="inset-shadow" >
<!-- dial up the opacity on the shape fill to "1" to select the full shape-->
<feComponentTransfer in="SourceAlpha" result="inset-selection">
<feFuncA type="discrete" tableValues="0 1 1 1 1 1"/>
</feComponentTransfer>

<!-- dial down the opacity on the shape fill to "0" to get rid of it -->
<feComponentTransfer in="SourceGraphic" result="original-no-fill">
<feFuncA type="discrete" tableValues="0 0 1"/>
</feComponentTransfer>

<!-- since you can't use the built in SourceAlpha generate your own -->
<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>
<!-- select the portion of the blur that overlaps with your shape -->
<feComposite operator="in" in="inset-selection" in2="blur" result="inset-blur"/>
<!-- composite the blur on top of the original with the fill removed -->
<feComposite operator="over" in="original-no-fill" in2="inset-blur"/>
</filter>

here is my fork of your fiddle: http://jsfiddle.net/kkPM4/

How to create an inset shadow(transparent background) in SVG?

It looks like you are creating a shape that is the outline of the a star rather than the whole shape being a star.

<!DOCTYPE html><html><body>
<svg width="260" height="245" xmlns="http://www.w3.org/2000/svg" fill="rgb(240, 240, 240)" stroke="transparent" stroke-width="1"> <filter id="inset-shadow" x="-50%" y="-50%" width="200%" height="200%"> <feComponentTransfer in=SourceAlpha> <feFuncA type="table" tableValues="1 0" /> </feComponentTransfer> <feGaussianBlur stdDeviation="1"/> <feOffset dx="0" dy="2" 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> <path filter="url(#inset-shadow)" d="M12 .587l3.668 7.568 8.332 1.151-6.064 5.828 1.48 8.279-7.416-3.967-7.417 3.967 1.481-8.279-6.064-5.828 8.332-1.151z"/> </svg> </body></html>

SVG - How to drop an inset shadow on a path that has an rgba fill?

Easiest way to do this is to do an inset-shadow - first resetting the source graphic's color to black/fully opaque.

<svg width="800px" height="600px" viewBox="0 0 400 300">
<defs>
<filter id="inset-shadow">
<feColorMatrix in="SourceGraphic" type="matrix" values="0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 100 0" result="opaque-source"/>
<feGaussianBlur stdDeviation="5"/>
<feOffset dy="10"/>
<feComposite operator="xor" in2="opaque-source"/>
<feComposite operator="in" in2="opaque-source"/>
<feComposite operator="over" in2="SourceGraphic"/>
</filter>
</defs>

<circle filter="url(#inset-shadow)" cx="100" cy="100" r="50" fill="rgba(0, 0, 0, 0.2)" />

<svg>

Inset shadows on svg are just acting as an outline

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>

How to create an inset shadow on an svg circle stroke?

Draw a pale grey stroked circle on a darker grey background, apply a gaussian blur filter, and clip the results with a clipPath:

<svg width="360" height="360" viewBox="0 0 180 180">  <defs>        <!-- Gaussian blur filter used to soften the shadow edges -->    <filter id="blur" filterUnits="userSpaceOnUse" x="-90" y="-90"            width="180" height="180">      <feGaussianBlur in="SourceGraphic" stdDeviation="1" />    </filter>        <!-- Annular clip path for the progress meter background -->    <clipPath id="ring" clip-rule="evenodd">      <path d="M0-81A81 81 0 0 1 0 81A81 81 0 0 1 0-81z               M0-63A63 63 0 0 1 0 63A63 63 0 0 1 0-63z" />    </clipPath>      </defs>    <!-- Set orgin to centre of drawing -->  <g transform="translate(90,90)">      <!-- Start with pale yellow background -->    <rect x="-90" y="-90" width="180" height="180" fill="#e8e0ce"          stroke="none" />        <!-- Draw the progress ring on top, and clip using the above clip path -->    <g clip-path="url(#ring)">
<!-- Dark grey background --> <rect x="-85" y="-85" width="170" height="170" fill="#433" stroke="none" />
<!-- Lighter grey circle with blur filter applied --> <circle cx="0" cy="2.5" r="72" stroke="#655" stroke-width="18" stroke="#655" fill="none" filter="url(#blur)"/> </g> <!-- Progress bar and text --> <path class="main-arc" d="M 0 -72 A 72 72 0 1 1 -4.52 -71.86" style="stroke-dasharray: 452.389; stroke-dashoffset: 366.435;" fill="transparent" stroke-width="18" stroke="#b65" stroke-linecap="round" /> <text x="0" y="0" font-size="40" font-family="'Trebuchet MS', sans-serif" fill="#655" text-anchor="middle" dominant-baseline="central"> 20% </text> </g></svg>

SVG - Inset and drop shadow at the same time

It depends on exactly what you want to do (the order matters), but you can e.g combine the two filters into one, like this:

<filter id="inset-and-drop-shadow" primitiveUnits="objectBoundingBox" x="0%" y="0%">
<feOffset dx="0.01" dy="0.02" />
<feGaussianBlur stdDeviation="0.01" result="offset-blur" />
<feComposite operator="out" in="SourceGraphic" in2="offset-blur" result="inverse" />
<feFlood flood-color="black" flood-opacity="1" result="color" />
<feComposite operator="in" in="color" in2="inverse" result="shadow" />
<feComposite operator="over" in="shadow" in2="SourceGraphic" result="inset-shadow" />
<feGaussianBlur in="SourceAlpha" stdDeviation="0.0012" />
<feOffset dx="0.006" dy="0.013" result="offsetblur" />
<feFlood flood-color="black" />
<feComposite in2="offsetblur" operator="in" />
<feMerge>
<feMergeNode/>
<feMergeNode in="inset-shadow" />
</feMerge>
</filter>

See fiddle.

SVG drop shadow using css3

Here's an example of applying dropshadow to some svg using the 'filter' property. If you want to control the opacity of the dropshadow have a look at this example. The slope attribute controls how much opacity to give to the dropshadow.

Relevant bits from the example:

<filter id="dropshadow" height="130%">
<feGaussianBlur in="SourceAlpha" stdDeviation="3"/> <!-- stdDeviation is how much to blur -->
<feOffset dx="2" dy="2" result="offsetblur"/> <!-- how much to offset -->
<feComponentTransfer>
<feFuncA type="linear" slope="0.5"/> <!-- slope is the opacity of the shadow -->
</feComponentTransfer>
<feMerge>
<feMergeNode/> <!-- this contains the offset blurred image -->
<feMergeNode in="SourceGraphic"/> <!-- this contains the element that the filter is applied to -->
</feMerge>
</filter>
<circle r="10" style="filter:url(#dropshadow)"/>

Box-shadow is defined to work on CSS boxes (read: rectangles), while svg is a bit more expressive than just rectangles. Read the SVG Primer to learn a bit more about what you can do with SVG filters.

add drop-shadow to svg polygon

You can apply the drop-shadow filter to the SVG OR use the SVG as a background of an element and apply filter to it:

polygon {  fill: #5091b9;  stroke: #4387b0;  stroke-width: 2;}.filter {  filter: drop-shadow(10px 0 5px red);}
.box { height: 100px; width: 100px; background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" width="100"><g transform="translate(50, 50)"><polygon stroke="%234387b0" stroke-width="2" fill="%235091b9" points="25.98076211353316,-14.999999999999998 25.98076211353316,14.999999999999998 1.83697019872103e-15,30 -25.98076211353316,14.999999999999998 -25.980762113533157,-15.000000000000004 -5.510910596163089e-15,-30" ></polygon></g></svg>');}
<p>SVG element</p><svg viewBox="0 0 100 100" width="100" class="filter"><g transform="translate(50, 50)" ><polygon points="25.98076211353316,-14.999999999999998 25.98076211353316,14.999999999999998 1.83697019872103e-15,30 -25.98076211353316,14.999999999999998 -25.980762113533157,-15.000000000000004 -5.510910596163089e-15,-30" ></polygon></g></svg><p>SVG as background</p><div class="box filter"></div>


Related Topics



Leave a reply



Submit