You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用stroke-dasharray的SVG饼图:扇区box-shadow无法生效求助

如何为stroke-dasharray实现的SVG饼图扇区添加不改变尺寸的阴影效果?

我通过stroke-dasharray实现了SVG饼图,现在需要给特定扇区添加阴影来标记激活状态,但遇到了问题:

  • 直接用CSS的filter: drop-shadow(0 4px 25px rgba(0, 0, 0, 0.75))没有效果
  • 尝试在SVG内部集成<filter>,却导致扇区整体尺寸被改变

预期效果如下:
预期效果示意图

示例代码

CSS代码

body {
  padding: 1rem;
  background: #bbb;
  text-align: center;
}

svg:not(:root) {
  overflow: visible;
}

svg {
  height: 280px;
  width: 280px;
  border: 20px solid white;
  border-radius: 50%;

  [id="1"] {
    filter: drop-shadow(0 4px 25px rgba(0, 0, 0, 0.75));
  }
}

HTML代码

<!-- 4 Elements -->
<svg height="20" width="20" viewBox="0 0 20 20">
  <circle id="1" r="5" cx="10" cy="10"
          stroke="tomato"
          stroke-width="10"
          stroke-dasharray="calc(90 * 31.42 / 360) 31.42"
          transform="rotate(-90)"
          transform-origin="center center"
   />
    <circle r="5" cx="10" cy="10" fill="transparent"
          stroke="blue"
          stroke-width="10"
          stroke-dasharray="calc(90 * 31.42 / 360) 31.42"
          transform-origin="center center"
   />
      <circle r="5" cx="10" cy="10" fill="transparent"
          stroke="yellow"
          stroke-width="10"
          stroke-dasharray="calc(90 * 31.42 / 360) 31.42"
          transform="rotate(90) scale(1.15)"
          transform-origin="center center"
   />
        <circle r="5" cx="10" cy="10" fill="transparent"
          stroke="green"
          stroke-width="10"
          stroke-dasharray="calc(90 * 31.42 / 360) 31.42"
          transform="rotate(180)"
          transform-origin="center center"
   />
</svg>

解决方法

方法一:自定义SVG Filter并调整边界

SVG默认的filter会将元素边界作为阴影的范围,导致元素被挤压。我们可以通过调整filter的x、y、width、height参数,给阴影留出足够空间,同时不影响原扇区尺寸。

修改后的SVG代码:

<svg height="20" width="20" viewBox="0 0 20 20">
  <!-- 定义阴影滤镜 -->
  <defs>
    <filter id="sectorShadow" x="-20%" y="-20%" width="140%" height="140%">
      <feDropShadow dx="0" dy="4" stdDeviation="12" flood-color="rgba(0,0,0,0.75)"/>
    </filter>
  </defs>

  <circle id="1" r="5" cx="10" cy="10"
          stroke="tomato"
          stroke-width="10"
          stroke-dasharray="calc(90 * 31.42 / 360) 31.42"
          transform="rotate(-90)"
          transform-origin="center center"
          filter="url(#sectorShadow)"
   />
    <!-- 其他扇区代码不变 -->
    <circle r="5" cx="10" cy="10" fill="transparent"
          stroke="blue"
          stroke-width="10"
          stroke-dasharray="calc(90 * 31.42 / 360) 31.42"
          transform-origin="center center"
   />
      <circle r="5" cx="10" cy="10" fill="transparent"
          stroke="yellow"
          stroke-width="10"
          stroke-dasharray="calc(90 * 31.42 / 360) 31.42"
          transform="rotate(90) scale(1.15)"
          transform-origin="center center"
   />
        <circle r="5" cx="10" cy="10" fill="transparent"
          stroke="green"
          stroke-width="10"
          stroke-dasharray="calc(90 * 31.42 / 360) 31.42"
          transform="rotate(180)"
          transform-origin="center center"
   />
</svg>

说明:

  • x="-20%"和y="-20%"让滤镜范围向上下左右扩展20%
  • width="140%"和height="140%"保证滤镜覆盖足够区域,阴影不会被截断
  • stdDeviation控制阴影模糊程度,可根据需求调整

方法二:双重元素模拟阴影

复制目标扇区元素,将底层元素仅用于显示阴影,上层放置原扇区。这种方法兼容性更好,不会受SVG filter边界的影响。

修改后的目标扇区代码:

<svg height="20" width="20" viewBox="0 0 20 20">
  <!-- 底层阴影元素 -->
  <circle r="5" cx="10" cy="10"
          stroke="tomato"
          stroke-width="10"
          stroke-dasharray="calc(90 * 31.42 / 360) 31.42"
          transform="rotate(-90)"
          transform-origin="center center"
          filter="drop-shadow(0 4px 25px rgba(0, 0, 0, 0.75))"
   />
  <!-- 上层原扇区元素 -->
  <circle id="1" r="5" cx="10" cy="10"
          stroke="tomato"
          stroke-width="10"
          stroke-dasharray="calc(90 * 31.42 / 360) 31.42"
          transform="rotate(-90)"
          transform-origin="center center"
   />
  <!-- 其他扇区代码不变 -->
</svg>

说明:

  • 底层元素的阴影会被上层元素覆盖中间部分,只露出边缘阴影,符合预期效果
  • 如果需要调整阴影颜色或透明度,直接修改底层元素的filter参数即可

内容的提问来源于stack exchange,提问作者Mizu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 14:48:14