【问题标题】:SVG - How to drop an inset shadow on a path that has an rgba fill?SVG - 如何在具有 rgba 填充的路径上放置嵌入阴影?
【发布时间】:2020-10-13 18:52:24
【问题描述】:

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

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

如何删除透明度与形状填充无关的可配置(颜色、模糊、位置)嵌入阴影?

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

【问题讨论】:

  • 再画一个圆圈。
  • 添加了效果图,如你所见,我不能再画一个圆圈了。

标签: svg svg-filters


【解决方案1】:

而不是画一个圆,而是画一个代表一个有洞的矩形的路径,并将过滤器应用到这个路径。

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

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

【讨论】:

  • 这很聪明,但是我用例中的 svg 独立于它背后的对象和颜色(这是一个渐变),并且不能是抠图。
  • 我不知道我还能如何进一步指定它,它似乎切入正题,但我添加了一个注释,即 SVG 必须独立于它背后的任何东西,如果这样的话更清晰。
  • 我需要了解什么部分应该是透明的?我的代码中的圆圈实际上是一个洞:完全透明。
  • 圆圈本身在未知颜色背景上是半透明的。我意识到在你的情况下,它实际上是一个穿过顶层的洞,它有一个填充,下面是另一种颜色,但我不知道你所拥有的顶层或底层的颜色是什么,我需要圆形以具有半透明填充(在我的情况下为黑色或白色)以与背景混合。我可能已经用一些过滤器解决了它codepen.io/salsita/pen/qBbmYMw
【解决方案2】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-15
    • 2018-12-19
    • 2019-04-26
    • 2016-07-16
    • 2015-11-29
    • 1970-01-01
    相关资源
    最近更新 更多