给SVG多边形添加投影效果

10
在附加的代码片段中,我有一个多边形,我需要添加一个效果,使它看起来像这样:enter image description here 我不知道如何在svg中实现这一点,如果是html我想我会使用box-shadow。唯一似乎可行的解决方案是使用filter,但我认为我只能在<svg/>元素上使用它,所以我很困惑该怎么做。

polygon {
  fill: #5091b9;
  stroke: #4387b0;
  stroke-width: 2;
}
<svg width="300" height="300">
  <g transform="translate(100, 100)">
    <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" class="node-vertical__hexagon node-vertical__inactive">         </polygon>
  </g>
</svg>


1
是的,您可以在SVG上使用drop-shadow滤镜,并且多边形周围会有阴影。 - Temani Afif
我有很多这些多边形。你的意思是说我在svg元素中嵌套了svg元素? - dagda1
如果在同一个 SVG 中有许多元素,所有元素都会获得阴影效果。 - Temani Afif
你可以将你的滤镜保存为一个带有defs的独立SVG文件,并通过use xlink:href应用它们。 - Chris W.
为了避免混淆,SVG过滤器用于HTML或SVG内容元素上的使用,请参阅[CSS过滤器规范](https://www.w3.org/TR/filter-effects-1/)。不需要使用`<use>标签,您可以通过CSS的url()函数来引用它们。如果在<svg>元素本身上使用它们,甚至可能会出现[意外问题](https://stackoverflow.com/questions/51295274),特别是与viewBox`结合使用时。 - ccprog
2个回答

18

您可以对SVG应用drop-shadow滤镜,或者将SVG用作元素的背景并对其应用滤镜:

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>

你也可以考虑使用SVG滤镜:

.node-vertical__inactive {
  filter:url(#shadow);
}

.node-vertical__hexagon {
  fill: #5091b9;
  stroke: #4387b0;
  stroke-width: 2;
}
<svg>
<defs>
    <filter id="shadow" x="-20%" y="-20%" width="200%" height="200%">
      <feDropShadow dx="20" dy="3" stdDeviation="5" flood-color="#5091b9" />
    </filter>
  </defs>
<g class="vx-group" transform="translate(0, 0)">
  <g class="vx-group node-vertical__container" transform="translate(100, 100)"><svg class="node-vertical__inactive" x="0" y="0" style="overflow: visible;"><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" class="node-vertical__hexagon"></polygon></svg>
</g>
</g>
</svg>


比我想象的要好得多,加一。 - Chris W.
你知道为什么这个 http://jsfiddle.net/dagda1/k0eocxfL/40/ fiddle 中的过滤器没有应用到我的源代码中吗?我需要嵌套SVG才能实现。难道过滤器不能应用于嵌套的SVG吗? - dagda1
@dagda1 我认为CSS过滤器在嵌套的SVG中不起作用.. 在这种情况下,您可以考虑使用SVG过滤器,请查看我的更新。 - Temani Afif
@dagda1 它在Firefox上能够工作。但是其他一些浏览器对于将CSS滤镜应用于SVG内容方面存在限制。 - Robert Longson
@RobertLongson 你有没有想法如何改变SVG滤镜的颜色?令人惊讶的是我找不到如何做:/ - Temani Afif
1
flood-color="蓝色" - Robert Longson

6
您可以使用SVG feOffset、feGaussianBlur、feBlend来代替`feDropShadow。

<svg width="300" height="300">
    <defs>
    <filter id="poly" x="0" y="0" width="200%" height="200%">
      <feOffset result="offOut" in="SourceGraphic" dx="15" dy="15" />
      <feGaussianBlur result="blurOut" in="offOut" stdDeviation="5" />
      <feBlend in="SourceGraphic" in2="blurOut" mode="normal" />
    </filter>
  </defs>
  <g transform="translate(100, 100)">
  <polygon points="100,10 40,198 190,78 10,78 160,198"
  style="fill:lime;stroke:purple;stroke-width:5;fill-rule:nonzero;" filter="url(#poly)" />
  </g>
</svg>

This will help you to make shadows with the exact color of your SVG shape no matter what it is so you don't have to set a single color for its shadow. For more information about this technique, you can visit W3Schools.


嗯,但那些并不是技术上的阴影。如果你看一个真正的阴影,它不会反射出投射阴影物体的颜色。 - Robert Longson
2
@RobertLongson 嗯,不错,不透明物体的阴影确实是暗的,但透明物体呢?比如红色着色玻璃之类的。无论如何,我只是建议一种创建阴影的替代方法。 - Morteza Sadri
@RobertLongson 如果你想要一个黑色阴影,你必须在feOffset之前添加一个feColorMatrix原语:<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0" /> - Waruyama
1
@Waruyama 当然,你已经实现了一个feDropShadow,尽管没有浏览器可以做的内部优化。 - Robert Longson
@RobertLongson 这是正确的,但与feDropShadow不同,它适用于Internet Explorer和Edge。 - Waruyama

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接