SVG - 如何在具有 rgba 填充的路径上放置插入阴影?

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

假设我在 SVG 中有一个带有半透明黑色填充(或任何半透明颜色)的圆形(或任何形状):

<circle r="50" fill="rgba(0, 0, 0, 0.2)" />

如何放置透明度独立于形状填充的可配置(颜色、模糊、位置)插入阴影?

注意:我事先对背景一无所知,SVG必须是真正透明的,不是伪造的。

您没有画圆,而是画了一条代表带孔矩形的路径,并将滤镜应用于该路径。

你看到的金色圆圈实际上是在阴影路径后面绘制的一个矩形。

<svg viewBox="-100 -100 200 200" width="300"> 
  <defs>
    <filter id="f">
       <feGaussianBlur in="SourceAlpha" stdDeviation="5" result="desenfoque"></feGaussianBlur>
       <feOffset in="desenfoque" dx="3" dy="3" result="sombra"></feOffset>
       <feMerge>
         <feMergeNode in="sombra"></feMergeNode>
         <feMergeNode in="SourceGraphic"></feMergeNode>
       </feMerge>
    </filter>
  </defs>
  <rect x="-100" y="-100" width="200" height="200" fill="gold" />
  <path fill="yellow" d="M-100,-100v200h200v-200h-200M50,0A50,50 0 0 1 -50,0A50,50 0 0 1 50,0z" filter="url(#f)" />
</svg>

最简单的方法是做一个嵌入阴影 - 首先将源图形的颜色重置为 black/fully 不透明。

<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>

或者您可以使用灯光效果来完成此操作 - 更复杂,而且性能可能参差不齐。

<svg width="800px" height="600px" viewBox="0 0 400 300">
  <defs>
    <filter id="top-light">
      <feColorMatrix type="matrix" values="1 0 0 0 0 
        0 1 0 0 0 
        0 0 1 0 0 
        0 0 0 100 0"/>
      <feGaussianBlur stdDeviation="2"/>
      <feComposite operator="in" in2="SourceGraphic"/>
      <feDiffuseLighting surfaceScale="200" diffuseConstant="1" kernelUnitLength="1" lighting-color="white" result="lightmap">
        <fePointLight x="100" y="0" z="10" />
      </feDiffuseLighting>
      <feGaussianBlur stdDeviation="2"/>
      
    <feColorMatrix type="luminanceToAlpha" />
    
    // Insert another color matrix in here to recolor the shadow
     <feComposite operator="in" in2="SourceGraphic"/>
      <feComposite operator="over" in2="SourceGraphic"/>

     
    </filter>
  </defs>
  
  <circle filter="url(#top-light)" cx="100" cy="100" r="50" fill="rgba(0, 0, 0, 0.2)" />
  
  <svg>