防止具有Alpha通道的重叠图形相互遮挡?

时间:2018-10-18 19:57:35

标签: svg mix-blend-mode

考虑一个带有两个部分重叠的圆圈的SVG,两个圆圈都带有fill="currentColor"。我无法控制当前颜色的值,可以通过我无法控制的代码将其设置为任何颜色。

我希望整个图形都具有相同的纯色。如果图像碰巧有例如color: red。但是,当当前颜色具有alpha通道时,圆圈重叠的部分会变暗。

我想避免这种情况。基本上,在此示例中,我想使第一张图片看起来像第二张图片:

<svg viewBox="0 0 10 10" style="color: rgba(0,0,0,50%); width: 100px;">
    <circle cx="3" cy="5" r="3" fill="currentColor"></circle>
    <circle cx="7" cy="5" r="3" fill="currentColor"></circle>
</svg>
<svg viewBox="0 0 10 10" style="color: rgb(50%,50%,50%); width: 100px;">
    <circle cx="3" cy="5" r="3" fill="currentColor"></circle>
    <circle cx="7" cy="5" r="3" fill="currentColor"></circle>
</svg>

是否可以使用混合模式来实现?

2 个答案:

答案 0 :(得分:2)

实现所需目标的一种简单方法就是将圆圈变成剪切路径。

<svg viewBox="0 0 10 10" style="color: rgba(0,0,0,50%); width: 100px;">
  <defs>
    <clipPath id="myClip">
      <circle cx="3" cy="5" r="3"></circle>
      <circle cx="7" cy="5" r="3"></circle>
    </clipPath>
  </defs>
  <rect width="100%" height="100%" fill="currentColor" clip-path="url(#myClip)"/>
</svg>

答案 1 :(得分:1)

如果您的目标只是将颜色移到完全不透明,则可以使用相对简单的滤镜来实现:

<svg viewBox="0 0 10 10" style="color: rgba(0,0,0,50%); width: 100px;">
    <filter id="filter">
        <feComponentTransfer in="SourceGraphic">
            <feFuncA type="linear" slope="100"/>
        </feComponentTransfer>
    </filter>
    <circle cx="3" cy="5" r="3" fill="currentColor" style="filter:url(#filter)"></circle>
    <circle cx="7" cy="5" r="3" fill="currentColor" style="filter:url(#filter)"></circle>
</svg>
<svg viewBox="0 0 10 10" style="color: rgb(50%,50%,50%); width: 100px;">
    <circle cx="3" cy="5" r="3" fill="currentColor"></circle>
    <circle cx="7" cy="5" r="3" fill="currentColor"></circle>
</svg>

如您所描述的,如果您想模拟透明背景在彩色背景上的效果,则要复杂一些,并且结果并不十分完美。

以下内容在每个彩色对象的轮廓后面分别添加了白色背景。

但是请注意两个属性:

  • color-interpolation-filters:sRGB是正确添加颜色所必需的
  • 在没有shape-rendering:crispEdges的情况下,您会得到一些物体重叠的伪影。但是,设置此功能是有代价的:您到处都会失去抗锯齿功能。视所使用的形状而定,这可能非常明显。

<svg viewBox="0 0 10 10" style="color: rgba(0,0,0,50%); width: 100px; shape-rendering:crispEdges">
    <filter id="filter" style="color-interpolation-filters:sRGB">
        <feFlood flood-color="#fff" flood-opacity="1" result="bg" />
        <feComponentTransfer in="SourceGraphic" result="opaque">
            <feFuncA type="linear" slope="100"/>
        </feComponentTransfer>
        <feComposite in="bg" in2="opaque" operator="in" result="combine" />
        <feComposite in="SourceGraphic" in2="combine" operator="atop" />
    </filter>
    <circle cx="3" cy="5" r="3" fill="currentColor" style="filter:url(#filter)"></circle>
    <circle cx="7" cy="5" r="3" fill="currentColor" style="filter:url(#filter)"></circle>
</svg>
<svg viewBox="0 0 10 10" style="color: rgb(50%,50%,50%); width: 100px;">
    <circle cx="3" cy="5" r="3" fill="currentColor"></circle>
    <circle cx="7" cy="5" r="3" fill="currentColor"></circle>
</svg>