防止具有 alpha 通道的重叠图形相互遮蔽?

Prevent overlapping figures with alpha channel from shading each other?

考虑一个 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>

这是否可能实现,也许使用混合模式?

如果您的目标是简单地将颜色移动到完全不透明,这可以通过相对简单的滤镜来实现:

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

要实现您想要的效果,一个简单的方法就是将圆圈变成剪切路径。

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