防止具有 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>
考虑一个 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>