【问题标题】:SVG: Showing average color for overlapping shapesSVG:显示重叠形状的平均颜色
【发布时间】:2021-08-07 23:51:48
【问题描述】:

这与Using SVG for additive color mixing (additive blending) 不同,后者专门讨论加法混合。为此,它就像设置mix-blend-mode: screen 一样简单。据我所知,没有混合混合模式可以平均颜色。如那里的答案所述,对此的答案可能确实涉及使用过滤器;但是问题如何

我正在制作一个应用程序,您可以在其中查看一些 SVG 数据。 SVG 具有不同颜色的图层,其中包含各种形状/路径。图层的颜色和形状/路径是输入并变化的。

一个示例 SVG 可能如下所示:

<svg>
  <g fill="#ff0000" id="layer1">
    <path d="M0,50 a50 50 0 1 1 100,0 a50 50 0 1 1 -100,0"/>
  </g>
  <g fill="#00ff00" id="layer2">
    <path d="M25,50 a50 50 0 1 1 100,0 a50 50 0 1 1 -100,0"/>
  </g>
  <g fill="#0000ff" id="layer3">
    <path d="M12.5,75 a50 50 0 1 1 100,0 a50 50 0 1 1 -100,0"/>
  </g>
  <!-- more layers... -->
</svg>

看起来像下图中的第一组圆圈(普通)。

我想要的是能够切换“透明模式”,这样您就可以看到隐藏在其他形状下方的形状。因此,如果两个形状在一个区域中重叠,则该区域的颜色应该是两个图层颜色的平均值。如果只有一个形状不重叠任何东西,颜色应该只是图层的颜色。 平均而言,我的意思是如果颜色“#00ff00”之上还有颜色“#ff0000”,则生成的颜色应该是“#7f7f00”。

我可以通过将所有内容绘制两次来获得弱透明效果(中间图片):以完全不透明度绘制所有内容,然后以一半不透明度再次在顶部绘制。但是效果很弱,并没有真正显示出真正的“混合”颜色。

这张图希望能说明我想要的效果(右图):

只要最终结果看起来正确,我不介意使用一些 hacky 来实现这一点。

【问题讨论】:

    标签: javascript html css svg svg-filters


    【解决方案1】:

    如果你想搞些怪事,你可以配对两个mix-blend-mode exclusion & multiply

    path {
      mix-blend-mode: exclusion;
    }
    
    .multiply path {
      opacity: 0.5;
      mix-blend-mode: multiply;
    }
    <svg>
      <g fill="#ff0000" id="layer1">
        <path d="M0,50 a50 50 0 1 1 100,0 a50 50 0 1 1 -100,0"/>
      </g>
      <g fill="#00ff00" id="layer2">
        <path d="M25,50 a50 50 0 1 1 100,0 a50 50 0 1 1 -100,0"/>
      </g>
      <g fill="#0000ff" id="layer3">
        <path d="M12.5,75 a50 50 0 1 1 100,0 a50 50 0 1 1 -100,0"/>
      </g>
    <g class="multiply">
      <g fill="#ff0000">
        <path d="M0,50 a50 50 0 1 1 100,0 a50 50 0 1 1 -100,0"/>
      </g>
      <g fill="#00ff00">
        <path d="M25,50 a50 50 0 1 1 100,0 a50 50 0 1 1 -100,0"/>
      </g>
      <g fill="#0000ff">
        <path d="M12.5,75 a50 50 0 1 1 100,0 a50 50 0 1 1 -100,0"/>
      </g>
    </g>
    </svg>

    【讨论】:

    • 谢谢查尔斯!这个 sn-p 在我的浏览器中工作,看起来应该!我在让这个解决方案工作时遇到了一些麻烦。当我将您发布的 SVG 和 CSS 复制到 HTML 文档中时,它看起来颜色不正确。这个具有相同代码的 jsfiddle 看起来也颜色不正确:jsfiddle.net/hwuke2mc 我不确定为什么它在 sn-p 中有效,但在其他地方无效?另外,您介意解释一下为什么会这样吗?
    • 有趣的是,它确实适用于 codepen:codepen.io/joesalerno/pen/ExWNaOm。但是我仍然无法让它处理我计算机上的文件。我尝试将 CSS 放在外部文件中,并将其内联,但它似乎希望看起来像我发布的那个 jsfiddle 链接中的那样。我不确定发生了什么。
    • 实际上它适用于 Firefox 的所有情况。但在 Edge 中,它只适用于 sn-p 和 codepen。任何想法如何让它为 Edge 工作?总的来说,这里发生了什么?感谢您的帮助!作为参考,这就是我在 Edge 中的解决方案:imgur.com/RYsYyCI
    • sn-p 在 Edge 中对我来说似乎工作正常。 Win 10 上的版本 90.0.818.62(官方构建)(64 位)。
    • 我可以确认它在较新的边缘版本上也适用于我。似乎在较旧的版本中, mix-blend-mode:exclusion 在空白背景下的工作方式不同。版本之间可能存在其他一些差异。不过,我仍然很好奇为什么它在所有情况下都适用于 codepen 和 stackoverflow sn-ps。这个解决方案对我来说似乎很神奇。很高兴了解它是如何工作的!但它确实有效。
    【解决方案2】:

    这不是完美的结果。但你可能会有渐进的不透明度。

    #layer1 {
     opacity: 1
    }
    
    #layer2 {
     opacity: .7
    }
    
    #layer3 {
     opacity: .5
    }
    <svg>
      <g fill="#ff0000" id="layer1">
        <path d="M0,50 a50 50 0 1 1 100,0 a50 50 0 1 1 -100,0"/>
      </g>
      <g fill="#00ff00" id="layer2">
        <path d="M25,50 a50 50 0 1 1 100,0 a50 50 0 1 1 -100,0"/>
      </g>
      <g fill="#0000ff" id="layer3">
        <path d="M12.5,75 a50 50 0 1 1 100,0 a50 50 0 1 1 -100,0"/>
      </g>
      <!-- more layers... -->
    </svg>

    【讨论】:

      猜你喜欢
      • 2019-01-31
      • 1970-01-01
      • 1970-01-01
      • 2020-12-29
      • 2014-01-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多