如何在 SVG 中制作插入阴影 [英] How to make an inset drop shadow in SVG

查看:52
本文介绍了如何在 SVG 中制作插入阴影的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要制作一个带有内嵌阴影的框,就像 CSS3 有内嵌框阴影一样.到目前为止,我发现的是一个带有 feGaussianBlur 的过滤器,但问题是它还在框外添加了一个阴影,这是我不想要的.这是我目前得到的代码:

I need to make a box with an inset drop shadow, in the same way that CSS3 has inset box-shadows. What I've found so far is a filter with feGaussianBlur, but the problem with that is that it also adds a drop shadow outside the box, which I don't want. Here's the code I've got so far:

<svg>
    <defs>
        <filter id="drop-shadow">
            <feGaussianBlur in="SourceAlpha" result="blur" stdDeviation="5" />
            <feGaussianBlur in="SourceAlpha" result="blur2" stdDeviation="10" />
            <feGaussianBlur in="SourceAlpha" result="blur3" stdDeviation="15" />
            <feMerge>
                <feMergeNode in="blur" mode="normal"/>
                <feMergeNode in="blur2" mode="normal"/>
                <feMergeNode in="blur3" mode="normal"/>
                <feMergeNode in="SourceGraphic" mode="normal"/>
            </feMerge>
        </filter>
    </defs>
    <rect x="10" y="10" width="100" height="100"
    stroke="black" stroke-width="4" fill="transparent" filter="url(#drop-shadow)"/>
</svg>

我制作了一个演示,该演示还将此代码与所需的 CSS 制作结果进行了比较.过滤器不仅适用于矩形,还适用于梯形和更复杂的多边形.

I've made a demo that also compares this code with the desired CSS-made result. The filter should not just work on rectangles, but also on trapezoids and more complicated polygons.

我已经尝试过使用radialGradient,但由于这会使渐变呈圆形,所以也不好.

I've already tried using radialGradient, but since that makes the gradient circular, that's not good either.

推荐答案

如果你有一个实心填充,你可以添加

If you had a solid fill, you could just add

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

到过滤器的末尾,它会将模糊剪辑到 SourceGraphic 的形状.由于您的形状是透明的,因此您需要做更多的工作.我的建议是在原始图形上使用半透明填充,以获得正确的合成选择,并使用 feFuncA 将最终操作的填充归零.事实证明,这出奇地复杂.但这里有一个适用于任何实线形状的解决方案

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>

这是我的小提琴分支:http://jsfiddle.net/kkPM4/

这篇关于如何在 SVG 中制作插入阴影的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆