Предотвратить перекрывающиеся друг с другом фигуры с альфа-каналом? - PullRequest
0 голосов
/ 18 октября 2018

Рассмотрим SVG с двумя частично перекрывающимися кругами, оба с fill="currentColor".Я не контролирую значение текущего цвета, оно может быть установлено с помощью кода, который я не могу контролировать.

Я хочу, чтобы вся фигура имела одинаковый сплошной цвет.Это прекрасно работает, если изображения имеют, например, color: red.Однако, когда у текущего цвета есть альфа-канал, часть, где круги перекрываются, становится темнее.

Я хочу избежать этого.По сути, я хотел бы, чтобы первое изображение выглядело как второе в этом примере:

<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 голосов
/ 19 октября 2018

Простой способ достичь желаемого - просто превратить круги в обтравочный контур.

<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>
0 голосов
/ 19 октября 2018

Если ваша цель состоит в том, чтобы просто переместить цвет до полной непрозрачности, это может быть достигнуто с помощью относительно простого фильтра:

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