如何使插图阴影在SVG中 [英] How to make an inset drop shadow in SVG

查看:128
本文介绍了如何使插图阴影在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>

我做了一个 demo ,它还将此代码与所需的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天全站免登陆